如何在TypeORM中禁用迁移的事务包裹功能
TypeORM迁移禁用事务包裹的解决方法
你需要执行无法在事务中运行的迁移操作,但当前使用的TypeORM迁移会通过QueryRunner自动把所有查询包裹在事务里,以下是两种可行的禁用方案:
方案一:手动终止默认事务
TypeORM会为每个迁移自动启动事务,你可以先回滚这个默认事务,之后执行的查询就会脱离事务上下文:
import { MigrationInterface, QueryRunner } from 'typeorm'; export class migrationNameXXXXXXXXXXX implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise<void> { // 回滚默认启动的事务,脱离事务环境 await queryRunner.rollbackTransaction(); // 执行无需事务的SQL await queryRunner.query(` // 你的无事务SQL代码 `); } public async down(queryRunner: QueryRunner): Promise<void> { // 若回滚操作也不需要事务,同样先终止默认事务 await queryRunner.rollbackTransaction(); await queryRunner.query(` // 回滚用的SQL代码 `); } }
方案二:创建无事务的QueryRunner实例
直接创建一个新的QueryRunner,明确禁用自动启动事务的功能,用这个实例执行你的查询:
import { MigrationInterface, QueryRunner, getConnection } from 'typeorm'; export class migrationNameXXXXXXXXXXX implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise<void> { // 创建不自动启动事务的QueryRunner const nonTxQueryRunner = getConnection().createQueryRunner({ startTransaction: false }); try { // 执行无事务SQL await nonTxQueryRunner.query(` // 你的无事务SQL代码 `); } finally { // 用完记得释放实例 await nonTxQueryRunner.release(); } } public async down(queryRunner: QueryRunner): Promise<void> { const nonTxQueryRunner = getConnection().createQueryRunner({ startTransaction: false }); try { await nonTxQueryRunner.query(` // 回滚用的SQL代码 `); } finally { await nonTxQueryRunner.release(); } } }
注意事项
- 方案一操作更简便,适合大多数场景;方案二更彻底,适合需要完全独立查询环境的情况。
- 仅当你的操作绝对不能在事务中执行(比如部分数据库的DDL语句不支持事务、需要立即生效的全局配置操作等)时使用这些方法,正常的事务操作不要随意禁用事务。
内容的提问来源于stack exchange,提问作者Skylar
相关产品推荐
相关产品推荐

