跳转到主要内容

事务处理

创建和使用事务

事务可以使用 DataSourceEntityManager 来创建。 示例:

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 UNCOMMITTEDREAD COMMITTEDREPEATABLE READSERIALIZABLE):

  • MySQL
  • PostgreSQL
  • SQL Server

SQLite 默认事务隔离级别为 SERIALIZABLE,但如果启用了 共享缓存模式,事务可以使用 READ UNCOMMITTED 隔离级别。

Oracle 仅支持 READ COMMITTEDSERIALIZABLE 隔离级别。

使用 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 的信息。