Ela*_*lan 20 sql transactions rollback
在下面的代码中,如果在执行SQL语句时抛出任何异常,我们应该期望在事务未提交时对事务进行隐式回滚,它会超出范围并被处置掉:
using (DbTransaction tran = conn.BeginTransaction())
{
//
// Execute SQL statements here...
//
tran.Commit();
}
Run Code Online (Sandbox Code Playgroud)
以上是一种可接受的做法,还是应该捕获异常并显式调用tran.Rollback(),如下所示:
using (DbTransaction tran = conn.BeginTransaction())
{
try
{
//
// Execute SQL statements here...
//
tran.Commit();
}
catch
{
tran.Rollback();
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
Rem*_*anu 21
前任的.如果您在类似主题上查找MSND示例,例如TransactionScope
,它们都支持隐式回滚.这有很多原因,但我只会给你一个非常简单的原因:当你捕获异常时,事务可能已经回滚了.许多错误回滚挂起的事务,然后它们将控制权返回给客户端,其中ADO.Net 在事务已经回滚到服务器上之后引发CLR SqlException (1205 DEADLOCK是此类错误的典型示例),因此显式Rollback()
呼叫充其量只是一个无操作,更糟糕的是错误.DbTransaction
(例如SqlTransaction
)的提供者应该知道如何处理这种情况,例如.因为服务器和客户端之间存在明确的聊天,通知事务已经回滚的事实,并且该Dispose()
方法做了正确的事情.
第二个原因是事务可以嵌套,但ROLLBACK的语义是一个回滚回滚所有事务,所以你只需要调用一次(不像那样Commit()
只提交最内部事务,必须为每个事务调用配对)开始).再一次,Dispose()
做对了.
更新
MSDN示例SqlConnection.BeginTransaction()
实际上支持第二种形式,并Rollback()
在catch
块中进行显式处理.我怀疑技术作家只是打算在一个单独的样本中显示,Rollback()
并Commit()
注意他需要在周围添加第二个try/catch块Rollback
以避开我最初提到的一些问题.