跳至主内容区

事务

非官方测试版翻译

本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →

创建和使用事务

事务通过 DataSourceEntityManager 创建。 示例:

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

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

所有需要在事务中执行的操作都必须在回调函数内完成:

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

事务操作最重要的限制是必须始终使用提供的事务实体管理器实例—— 本例中的 transactionalEntityManager禁止使用全局实体管理器。 所有操作必须使用提供的事务实体管理器执行。

指定隔离级别

可通过在第一个参数位置指定隔离级别:

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

隔离级别的实现并非在所有数据库中都通用。每个驱动程序都会声明其支持的隔离级别,如果您请求了不支持的级别,TypeORM 将抛出错误。

DriverSupported isolation levels
MySQL / MariaDBREAD UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE
PostgreSQLREAD UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE
CockroachDBREAD UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE
SQL ServerREAD UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE, SNAPSHOT
OracleREAD COMMITTED, SERIALIZABLE
SAP HANAREAD COMMITTED, REPEATABLE READ, SERIALIZABLE
SQLiteREAD UNCOMMITTED*, SERIALIZABLE
SpannerREAD UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE
  • SQLite 的 READ UNCOMMITTED 隔离级别仅在共享缓存模式启用时生效。在默认模式下,无论设置如何,SQLite 始终使用 SERIALIZABLE 隔离级别。

SQL Server 也支持通过数据源选项(isolationLevelconnectionIsolationLevel)设置默认隔离级别,但这些设置受到上游连接池限制的影响。每个事务的隔离级别不受此限制影响。

使用 QueryRunner 创建并控制单数据库连接状态

QueryRunner 提供单个数据库连接。 事务通过查询运行器进行管理。 单个事务只能在单个查询运行器上建立。 您可以手动创建查询运行器实例并控制事务状态。 示例:

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

QueryRunner 提供三种事务控制方法:

  • startTransaction - 在查询运行器实例内启动新事务

  • commitTransaction - 提交使用该查询运行器实例所做的所有更改

  • rollbackTransaction - 回滚使用该查询运行器实例所做的所有更改

了解更多关于查询运行器