EF Core 中开启事务很简单,核心是通过 DbContext.Database.BeginTransaction() 获取事务对象,再配合 SaveChanges() 和 Commit()/Rollback() 控制数据一致性。
使用显式事务(推荐)
适合需要跨多个 SaveChanges 调用、或混合执行原生 SQL 与实体操作的场景。
调用 BeginTransaction() 启动事务,返回DbContextTransaction在同一个 DbContext 实例中执行所有数据库操作(增删改、ExecuteSqlRaw 等) 全部成功则调用 transaction.Commit();出错时捕获异常并调用 transaction.Rollback() 注意:事务必须在 同一个 DbContext 实例 中使用,不能跨实例共享
使用 SaveChanges 自动事务(默认行为)
每次调用 SaveChanges() 或 SaveChangesAsync(),EF Core 默认会自动开启一个事务(如果当前没有活跃事务)。
这个事务只包裹本次 SaveChanges 的所有变更,执行完即提交 无需手动管理,适合单次数据写入操作 若想禁用自动事务(极少见),可配置context.Database.AutoTransactionsEnabled = false
嵌套事务与保存点(Savepoint)
EF Core 不支持真正的嵌套事务,但可通过 Savepoint 实现局部回滚。
调用 transaction.BeginSavepoint("name") 创建保存点 后续操作失败时,可用 savepoint.RollbackToSavepoint() 回滚到该点,不影响前面已提交的部分 适用于复杂业务中“部分失败可接受”的逻辑,比如批量导入时跳过个别脏数据异步事务操作
生产环境建议统一使用异步方法,避免线程阻塞。
用 BeginTransactionAsync() 替代 BeginTransaction() 用 CommitAsync() 和 RollbackAsync() 替代同步版本 确保整个调用链(包括 SaveChangesAsync)都是 async/await,避免死锁基本上就这些。事务本质是保障原子性,关键在于明确作用范围、及时释放资源、避免长时间持有连接。不复杂但容易忽略细节。
