Transazioni
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.