Saltar al contenido principal

Transacciones

Traducción Beta No Oficial

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

Creación y uso de transacciones

Las transacciones se crean usando DataSource o EntityManager. Ejemplos:

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

o

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

Todo lo que quieras ejecutar en una transacción debe realizarse en una devolución de llamada:

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

La restricción más importante al trabajar con transacciones es SIEMPRE usar la instancia proporcionada del gestor de entidades - en este ejemplo, transactionalEntityManager. NO USES EL GESTOR DE ENTIDADES GLOBAL. Todas las operaciones DEBEN ejecutarse usando el gestor de entidades transaccional proporcionado.

Especificación de niveles de aislamiento

Puedes especificar el nivel de aislamiento para la transacción proporcionándolo como primer parámetro:

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

Las implementaciones de niveles de aislamiento no son uniformes en todas las bases de datos.

Los siguientes controladores de base de datos soportan los niveles de aislamiento estándar (READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE):

  • MySQL

  • Postgres

  • SQL Server

SQLite establece por defecto SERIALIZABLE para transacciones, pero si está habilitado el modo shared cache, una transacción puede usar el nivel READ UNCOMMITTED.

Oracle solo soporta los niveles de aislamiento READ COMMITTED y SERIALIZABLE.

Uso de QueryRunner para crear y controlar el estado de conexiones únicas

QueryRunner proporciona una única conexión a la base de datos. Las transacciones se organizan mediante gestores de consultas (query runners). Las transacciones individuales solo pueden establecerse en un único gestor de consultas. Puedes crear manualmente una instancia de QueryRunner y usarla para controlar manualmente el estado de las transacciones. Ejemplo:

// 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()
}

Existen 3 métodos para controlar transacciones en QueryRunner:

  • startTransaction - inicia una nueva transacción dentro de la instancia del gestor de consultas (query runner).

  • commitTransaction - confirma todos los cambios realizados usando la instancia del gestor de consultas.

  • rollbackTransaction - revierte todos los cambios realizados usando la instancia del gestor de consultas.

Más información sobre Query Runner.