代码之家  ›  专栏  ›  技术社区  ›  Kent Boogaart

是否需要显式事务回滚?

  •  25
  • Kent Boogaart  · 技术社区  · 16 年前

    许多例子都提倡数据库事务的显式回滚,包括:

    using (var transaction = ...)
    {
        try
        {
            // do some reading and/or writing here
    
            transaction.Commit();
        }
        catch (SqlException ex)
        {
            // explicit rollback
            transaction.Rollback();
        }
    }
    

    但是,我倾向于这样做:

    using (var transaction = ...)
    {
        // do some reading and/or writing here
    
        transaction.Commit();
    }
    

    当发生异常时,我只是依赖于隐式回滚未提交的事务。

    依赖这种隐性行为有什么问题吗?有人有一个令人信服的理由为什么我不应该这样做吗?

    5 回复  |  直到 16 年前
        1
  •  14
  •   Justin    16 年前

    不,这不是特别需要的,但是我可以考虑两个原因,为什么它可能是一个好主意:

    • 清晰

    有些人可能会认为使用 transaction.Rollback() 更清楚地说明在什么情况下交易不会被提交。

    • 释放锁

    在处理事务时,重要的是要认识到只有在回滚或提交事务时才会释放某些锁。如果您正在使用 using 语句,则在释放事务时事务将回滚,但是如果出于某种原因,需要在 使用 块,在执行复杂/耗时的错误处理之前回滚事务(删除锁)可能比较有利。

        2
  •  4
  •   Jamie Ide    16 年前

    我发现你的使用有两个问题:

    1. 您依赖事务的Dispose()方法回滚未提交的事务,从而创建对第三方IDisposable实现的依赖关系。当然,在这种情况下,风险可以忽略不计,但这不是一个好的实践。
    2. 您缺少记录和/或处理异常的机会。另外,我会捕获异常,而不是sqlException。
        3
  •  1
  •   Lazarus    16 年前

    我想可以回答的是,第一种方法对于维护您的代码的人来说更易读。编码的显式特性使目标清晰、快速。虽然隐式回滚对您来说是清楚的,而且可能是任何对事务处理有过多了解的人,但对其他人来说可能不是。也就是说,一些评论会很快纠正这一点。唯一的问题是隐式回滚是否不是对象的文档化特性。

    所以,我想说,如果您对操作进行评论,并且可以依赖隐式操作,那么就没有很好的理由使用显式方法。

        4
  •  1
  •   LBushkin    16 年前

    最正确编写的ADO.NET连接将回滚未显式提交的事务。所以没有严格的必要。

    我看到的主要好处是 Rollback() 称之为在那里设置断点,然后检查连接或数据库以查看发生了什么。对于未来的代码维护人员来说,在不同的执行路径下会发生什么也更加清楚。

        5
  •  0
  •   Dave Markle    16 年前

    只要事务完全独立于using()块中,您就可以开始了。但是,如果有人从调用者那里传递了一个现有的事务对象,那么问题可能也确实会出现。但情况不同…