TypeORM使用typeorm-transactional-cls-hooked出现双事务问题如何解决?
多事务重叠问题解决方案
你遇到的多次启动事务问题核心原因是:提前在构造函数中从全局租户连接初始化了Repository实例,该实例不受@Transactional()注解的事务上下文管理,执行数据库操作时会独立开启新事务。
调整方案
代码修改
不要在构造函数中提前初始化全局Repository,改为在事务方法内从当前事务绑定的EntityManager中获取对应实体的Repository,修改后代码如下:
import { EntityManager, Not } from 'typeorm'; import { InjectEntityManager } from '@nestjs/typeorm'; import { Transactional } from 'typeorm-transactional-cls-hooked'; export class TestService { constructor( // 注入对应租户连接的EntityManager,不提前初始化Repository @InjectEntityManager(TENANT_CONNECTION) private entityManager: EntityManager ) {} @Transactional() async agregar(tableNew: Test): Promise<Number> { // 从当前事务上下文的EntityManager获取Repository,自动绑定事务 const testRepository = this.entityManager.getRepository(Test); const tableSave = testRepository.create(tableNew); await testRepository.save(tableSave); if(tableSave.default){ await testRepository.update( {default:true,id:Not(tableSave.id)}, {default:false} ); } return tableSave.id; } }
额外验证项
- 确保应用启动时已完成事务上下文初始化:如果使用
typeorm-transactional-cls-hooked库,需要在main.ts启动逻辑中调用initializeTransactionalContext()和patchTypeORM(),否则事务上下文无法正常传递 - 多租户场景下需确认
@Transactional注解绑定的连接名与租户连接名一致,若存在多连接隔离需求可以通过@Transactional({ connectionName: '你的租户连接标识' })指定 - 不要在非事务上下文中调用被
@Transactional修饰的方法,避免上下文丢失
内容的提问来源于stack exchange,提问作者Alan
相关产品推荐
相关产品推荐

