事务处理
创建和使用事务
事务可以使用 DataSource
或 EntityManager
来创建。
示例:
await myDataSource.transaction(async (transactionalEntityManager) => {
// 使用 transactionalEntityManager 执行查询
})
或者
await myDataSource.manager.transaction(async (transactionalEntityManager) => {
// 使用 transactionalEntityManager 执行查询
})
在事务中执行的所有操作必须在回调函数中执行:
await myDataSource.manager.transaction(async (transactionalEntityManager) => {
await transactionalEntityManager.save(users)
await transactionalEntityManager.save(photos)
// ...
})
在事务中工作的最重要的限制是始终使用提供的实体管理器实例 - 在此示例中为 transactionalEntityManager
。不要使用全局实体管理器。所有操作都必须使用提供的事务性实体管理器执行。
指定隔离级别
可以通过将其作为第一个参数提供来指定事务的隔离级别:
await myDataSource.manager.transaction(
"SERIALIZABLE",
(transactionalEntityManager) => {},
)
隔离级别的实现在所有数据库之间并不通用。
以下数据库驱动程序支持标准的隔离级别(READ UNCOMMITTED
、READ COMMITTED
、REPEATABLE READ
、SERIALIZABLE
):
- MySQL
- PostgreSQL
- SQL Server
SQLite 默认事务隔离级别为 SERIALIZABLE
,但如果启用了 共享缓存模式,事务可以使用 READ UNCOMMITTED
隔离级别。
Oracle 仅支持 READ COMMITTED
和 SERIALIZABLE
隔离级别。
使用 QueryRunner
创建和控制单个数据库连接的状态
QueryRunner
提供了单个数据库连接。事务使用查询运行器进行组织。单个事务只能建立在一个查询运行器上。您可以手动创建一个查询运行器实例,并使用它来手动控制事务状态。示例:
// 创建一个新的查询运行器
const queryRunner = dataSource.createQueryRunner()
// 使用我们的新查询运行器建立真实的数据库连接
await queryRunner.connect()
// 现在我们可以在查询运行器上执行任何查询,例如:
await queryRunner.query("SELECT * FROM users")
// 我们还可以访问使用查询运行器创建的连接的实体管理器:
const users = await queryRunner.manager.find(User)
// 现在让我们打开一个新的事务:
await queryRunner.startTransaction()
try {
// 在这个事务中执行一些操作:
await queryRunner.manager.save(user1)
await queryRunner.manager.save(user2)
await queryRunner.manager.save(photos)
// 现在提交事务:
await queryRunner.commitTransaction()
} catch (err) {
// 由于发生错误,让我们回滚所做的更改
await queryRunner.rollbackTransaction()
} finally {
// 您需要释放手动创建的查询运行器:
await queryRunner.release()
}
QueryRunner
有三种方法来控制事务:
startTransaction
- 在查询运行器实例内部启动一个新的事务。commitTransaction
- 提交使用查询运行器实例进行的所有更改。rollbackTransaction
- 回滚使用查询运行器实例进行的所有更改。
了解更多关于 Query Runner 的信息。