C# Entity Framework中实现事务回滚

Theo
Theo
发布时间:2026-10-15 | 4人浏览过
原创

在使用Entity Framework对关联的主从表进行数据添加时,若需保证多个表操作的原子性,可利用TransactionScope实现事务回滚。当部分操作失败时,数据库会自动撤销已提交的数据,确保数据一致性。

使用 TransactionScope 实现 EF 事务回滚

在C#的Entity Framework开发中,经常遇到需要在同一逻辑单元内对多个实体进行操作的情况。例如,同时插入“国家”和“州”两个表的数据。如果其中一个步骤失败(如代码抛出异常),我们希望之前成功写入的数据能够一并撤销,这就是事务回滚的核心作用。

以下展示了两张存在主外键关系的表结构示意图:

第一步:准备事务环境与上下文

目的:初始化用于管理分布式事务的范围和EF的数据库上下文。

  • 入口:使用 using (TransactionScope ts = new TransactionScope()) 包裹核心业务代码。
  • 动作:在事务范围内创建 EF 的 DbContext 实例(示例中为 CountryDetailsEntities)。
  • 参数:DbContext 也推荐使用 using 语句管理,确保资源释放。

第二步:执行主表与从表的添加操作

目的:模拟正常的业务数据插入流程。

  • 入口:构建实体对象并加入集合。
  • 动作:
    Country country = new Country();
    country.CountryName = "USA";
    db.Countries.Add(country);

    调用 db.SaveChanges() 将主表数据暂存至本地缓存,此时尚未真正同步到物理数据库(具体行为受EF版本和配置影响,但在TransactionScope上下文中会跟随事务提交)。

第三步:设置异常触发点与验证逻辑

目的:模拟在插入从表时发生错误,以测试回滚机制。

  • 输入参数:检查主表ID是否正确生成。if (country.CountryID > 0)。
  • 关键动作:执行可能导致异常的操作。示例中使用了 int total = 10 / a;(其中 a=0)来强制抛出 DivideByZeroException。
  • 观察状态:正常情况下应继续添加 State 对象:
    State state = new State();
    state.CountryID = country.CountryID;
    state.StateName = "NewYork";
    db.States.Add(state);

第四步:确认事务并提交或回滚

目的:根据执行结果决定是否让变更持久化。

  • 入口:ts.Complete() 放置在 using 块末尾。
    如果代码顺利执行至此,事务被标记为已完成;若在中间任何地方发生未捕获异常,程序跳转到 catch 块。
  • 完成判断:
    - 正常情况:调用 ts.Complete(),所有数据库操作被锁定并随事务一起提交。
    - 异常情况:进入 catch (Exception ex) { throw; } 区域。由于 TransactionScope 未收到 Complete 信号且检测到异常,会自动取消当前事务,之前对数据库的所有修改将被回滚。
class Program
{
    static void Main(string[] args)
    {
        try
        {
            using (TransactionScope ts = new TransactionScope())
            {
                using (CountryDetailsEntities db = new CountryDetailsEntities())
                {
                    // 1. 添加主表数据
                    Country country = new Country();
                    country.CountryName = "USA";
                    db.Countries.Add(country);
                    db.SaveChanges();

                    if (country.CountryID > 0)
                    {
                        // 2. 模拟异常:除以零
                        int a = 0;
                        int total = 10 / a;

                        // 3. 理论上不会执行到这里
                        State state = new State();
                        state.CountryID = country.CountryID;
                        state.StateName = "NewYork";
                        db.States.Add(state);
                        db.SaveChanges();
                    }
                }
                // 4. 只有无异常才会提交事务
                ts.Complete();
            }
        }
        catch (Exception ex)
        {
            // 5. 异常发生后,事务自动回滚,数据库中无任何新增记录
            throw;
        }
    }
}

总结

通过上述代码可以看出,TransactionScope 极大地简化了EF中的事务处理。无需手动编写复杂的SQL存储过程或显式开启/提交事务。一旦在执行链路上抛出异常,所有的 SaveChanges 都会失效。在实际生产环境中,建议将日志记录整合进 catch 块以便追踪问题根源。

以上就是关于 C# Entity Framework 中利用 TransactionScope 实现事务回滚的详细内容,更多关于数据库事务控制的相关资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表