我使用EF来调用这样的存储过程:
db.Database.ExecuteSqlCommand(sql, parameters);
这些过程会执行多次插入和更新。我在TRY的末尾添加了一个TRY区域和一个COMMIT,并在一个ROLLBACK(在一个CATCH内)逻辑但这给了我一个错误,我追溯到这个:
如果案例是EF包装存储过程调用,那么这意味着没有理由在存储过程中执行此操作,或者我应该在SP中保留COMMIT和ROLLBACK并执行此操作:
db.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, sql, parameters);
答案 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应用了模板保存点,效果很好。