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

时间:2016-01-27 06:02:55

标签: asp.net sql-server entity-framework stored-procedures entity-framework-6

我使用EF来调用这样的存储过程:

db.Database.ExecuteSqlCommand(sql, parameters);

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

Stackoverflow Explanation

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

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

3 个答案:

答案 0 :(得分:3)

如果可能的话,你不应该在存储过程中处理事务并使用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();
    }
}

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

答案 1 :(得分:0)

你可以这样做:

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

答案 2 :(得分:0)

回滚将回滚所有打开(活动)事务。如果使用EF,EF总是自动创建一个根(最外层)事务,这样存储过程中的回滚也会回滚由EF创建的事务,这将导致错误。 有一种方法可以克服,使用保存点 - >见https://msdn.microsoft.com/en-us/library/ms188378.aspx

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