EF Core 6.0中DbTransactionInterceptor是否始终会触发执行?
结论
这是Entity Framework Core的预期设计行为,并非框架bug。
两次拦截触发的原因
你运行代码得到两次transaction triggered输出,分别对应两个框架自动创建的隐式事务提交:
- 第一次触发来自
context.Database.EnsureCreated():和你推测的一致,EnsureCreated执行建库、建表等DDL操作时,会自动开启内部事务保证所有结构变更操作的原子性,避免建库流程中途中断留下残缺的数据库结构,事务提交时自然会命中TransactionCommitted拦截回调。 - 第二次触发来自
context.SaveChanges():这是EF Core的默认运行机制——即使开发者没有显式调用任何事务开启API,单次SaveChanges()提交的所有数据变更,默认都会被包裹在隐式事务中执行,保证本次提交的操作要么全部成功落库,要么全部回滚,不会出现部分写入的数据不一致问题,这个隐式事务提交时同样会触发事务拦截器。
仅拦截显式事务的参考实现
如果你的拦截逻辑只需要处理开发者手动开启的事务,可以通过拦截方法传入的事件参数结合上下文状态过滤隐式事务:
class TestTransactionInterceptor : DbTransactionInterceptor { public override void TransactionCommitted(DbTransaction transaction, TransactionEndEventData eventData) { // 框架自动创建的隐式事务在提交完成后会立即释放,触发回调时上下文的CurrentTransaction为空 // 手动开启的显式事务在提交完成、主动释放前,CurrentTransaction会持有事务实例 if (eventData.Context?.Database.CurrentTransaction == null) { return; } // 仅针对显式事务执行的拦截逻辑 Console.WriteLine("transaction triggered"); } }
内容的提问来源于stack exchange,提问作者Morten Toudahl
相关产品推荐
相关产品推荐

