Vai al contenuto principale

Transazioni

Traduzione Beta Non Ufficiale

Questa pagina è stata tradotta da PageTurner AI (beta). Non ufficialmente approvata dal progetto. Hai trovato un errore? Segnala problema →

Creazione e utilizzo delle transazioni

Le transazioni vengono create utilizzando DataSource o EntityManager. Esempi:

await myDataSource.transaction(async (transactionalEntityManager) => {
// execute queries using transactionalEntityManager
})

oppure

await myDataSource.manager.transaction(async (transactionalEntityManager) => {
// execute queries using transactionalEntityManager
})

Tutte le operazioni da eseguire in una transazione devono essere contenute in una callback:

await myDataSource.manager.transaction(async (transactionalEntityManager) => {
await transactionalEntityManager.save(users)
await transactionalEntityManager.save(photos)
// ...
})

La restrizione più importante quando si lavora in una transazione è UTILIZZARE SEMPRE l'istanza fornita dell'entity manager - transactionalEntityManager in questo esempio. NON UTILIZZARE L'ENTITY MANAGER GLOBALE. Tutte le operazioni DEVONO essere eseguite utilizzando l'entity manager transazionale fornito.

Specifica dei livelli di isolamento

È possibile specificare il livello di isolamento per la transazione fornendolo come primo parametro:

await myDataSource.manager.transaction(
"SERIALIZABLE",
(transactionalEntityManager) => {},
)

L'implementazione dei livelli di isolamento non è uniforme tra tutti i database.

I seguenti driver di database supportano i livelli di isolamento standard (READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE):

  • MySQL

  • Postgres

  • SQL Server

SQLite utilizza per impostazione predefinita SERIALIZABLE, ma se è abilitata la modalità cache condivisa, una transazione può utilizzare il livello di isolamento READ UNCOMMITTED.

Oracle supporta solo i livelli di isolamento READ COMMITTED e SERIALIZABLE.

Utilizzo di QueryRunner per creare e controllare lo stato di una connessione database singola

QueryRunner fornisce una singola connessione al database. Le transazioni vengono gestite tramite i query runner. È possibile stabilire una singola transazione solo su un singolo query runner. Puoi creare manualmente un'istanza di query runner e utilizzarla per controllare manualmente lo stato della transazione. Esempio:

// create a new query runner
const queryRunner = dataSource.createQueryRunner()

// establish real database connection using our new query runner
await queryRunner.connect()

// now we can execute any queries on a query runner, for example:
await queryRunner.query("SELECT * FROM users")

// we can also access entity manager that works with connection created by a query runner:
const users = await queryRunner.manager.find(User)

// lets now open a new transaction:
await queryRunner.startTransaction()

try {
// execute some operations on this transaction:
await queryRunner.manager.save(user1)
await queryRunner.manager.save(user2)
await queryRunner.manager.save(photos)

// commit transaction now:
await queryRunner.commitTransaction()
} catch (err) {
// since we have errors let's rollback changes we made
await queryRunner.rollbackTransaction()
} finally {
// you need to release query runner which is manually created:
await queryRunner.release()
}

Esistono 3 metodi per controllare le transazioni in QueryRunner:

  • startTransaction - avvia una nuova transazione all'interno dell'istanza del query runner.

  • commitTransaction - consolida tutte le modifiche apportate utilizzando l'istanza del query runner.

  • rollbackTransaction - annulla tutte le modifiche apportate utilizzando l'istanza del query runner.

Ulteriori informazioni su Query Runner.