我正在使用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 应用了模板保存点,效果很好。