加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

sql – 更好的做法是明确地调用事务回滚或让异常触发隐式回滚?

发布时间:2020-12-12 16:11:54 所属栏目:MsSql教程 来源:网络整理
导读:在下面的代码中,如果在执行SQL语句时抛出任何异常,我们应该期待事务的隐式回滚,因为事务没有提交,它超出了范围,它被处理: using (DbTransaction tran = conn.BeginTransaction()){ // // Execute SQL statements here... // tran.Commit();} 以上是可接受的
在下面的代码中,如果在执行SQL语句时抛出任何异常,我们应该期待事务的隐式回滚,因为事务没有提交,它超出了范围,它被处理:
using (DbTransaction tran = conn.BeginTransaction())
{
    //
    // Execute SQL statements here...
    //
    tran.Commit();
}

以上是可接受的做法,或者应该捕获异常并明确地调用tran.Rollback(),如下所示:

using (DbTransaction tran = conn.BeginTransaction())
{
    try
    {
        //
        // Execute SQL statements here...
        //
        tran.Commit();
    }
    catch
    {
        tran.Rollback();
        throw;
    }
}

解决方法

前任的.如果您查找类似主题的MSND样本,例如 TransactionScope,他们都赞成隐式回滚.有各种各样的原因,但我会给你一个非常简单的一个:当你捕获异常时,事务可能已经回滚了.许多错误回滚挂起的事务,然后将控制权返回给客户端,ADO.Net在事务已经在服务器上回滚之后引发了CLR SqlException(1205 DEADLOCK是这种错误的典型示例),因此显式Rollback()调用最多只是一个no-op,更糟糕的是一个错误. DbTransaction的提供者(例如SqlTransaction)应该知道如何处理这种情况,例如.因为服务器和客户端之间有明确的聊天,通知事务已经回滚,Dispose()方法做正确的事情.

第二个原因是事务可以嵌套,但是ROLLBACK的语义是一个回滚可以回滚所有事务,所以你只需要调用它一次(不同于Commit(),它只提交内部最多的事务,并且必须被配对每个开始).再次,Dispose()做正确的事情.

更新

SqlConnection.BeginTransaction()的MSDN示例实际上有利于第二种形式,并在catch块中显式显示Rollback().我怀疑技术作者只是想在一个单一的样本中显示Rollback()和Commit(),注意到他需要如何在Rollback周围添加一个第二个try / catch块,以规避我最初提到的一些问题.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读