对于 EF6,我是否需要在存储过程中使用 COMMIT 和 ROLLBACK



我正在使用EF调用存储过程,如下所示:

db.Database.ExecuteSqlCommand(sql, parameters);

这些过程执行多次插入和更新。我在 TRY 的末尾添加了一个 TRY 区域和一个 COMMIT 和一个回滚(在 CATCH 内部)逻辑,但这给了我一个错误,我可以追溯到这个:

堆栈溢出说明

如果情况是 EF 包装存储过程调用,那么这是否意味着没有理由在存储过程中执行此操作,或者我应该将 COMMIT 和 ROLLBACK 保留在 SP 中并执行以下操作:

db.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, sql, parameters);

如果可能的话,你不应该在存储过程中处理事务,而应该这样做,DbContexts 依赖于现有的连接和事务:

using (var conn = new SqlConnection("YourConnectionString"))
{
    conn.Open();
    using (var tran = conn.BeginTransaction())
    {
        using (var ctx1 = new DbContext(conn, false))
        {
            ctx1.Database.UseTransaction(tran);
            ctx1.Database.ExecuteSqlCommand("Exec YourStoredProc1");
            ctx1.Database.ExecuteSqlCommand("Exec YourStoredProc2");
        }
        using (var ctx2 = new DbContext(conn, false))
        {
            ctx2.Database.UseTransaction(tran);
            ctx2.Database.ExecuteSqlCommand("Exec YourStoredProc3");
        }
        tran.Commit();
    }
}

由于已提供事务,因此实体框架不会将调用包装在新事务中。当然,您可以使用try{}catch(){}处理错误的回滚逻辑,也可以使用您想要的任何业务代码来处理错误的回滚逻辑。

你可以这样做:

using (TransactionScope scope = new TransactionScope())
{
    //EF context
   using (TestDatabaseEntities contect = new TestDatabaseEntities())
    {
      //TODO:`enter code here`
    }
 }

回滚将回滚所有打开(活动)事务。如果使用 EF,EF 始终自动创建根(最外层)事务,以便存储进程内的回滚也会回滚 EF 创建的事务,并导致错误。有一种方法可以克服,使用保存点 -> 看到 https://msdn.microsoft.com/en-us/library/ms188378.aspx

我已经为 EF 应用了模板保存点,效果很好。

最新更新