如果发生错误,using 语句会回滚数据库事务吗?

Posted

技术标签:

【中文标题】如果发生错误,using 语句会回滚数据库事务吗?【英文标题】:Will a using statement rollback a database transaction if an error occurs? 【发布时间】:2010-10-13 02:27:54 【问题描述】:

我在 using 语句中有一个 IDbTransaction,但我不确定如果在 using 语句中引发异常,它是否会回滚。我知道 using 语句将强制调用 Dispose()...但是有谁知道 Rollback() 是否也是如此?

更新:另外,我是否需要像下面那样显式调用 Commit() 还是使用 using 语句也能解决这个问题?

我的代码看起来像这样:

using Microsoft.Practices.EnterpriseLibrary.Data;

...

using(IDbConnection connection = DatabaseInstance.CreateConnection())

    connection.Open();

    using(IDbTransaction transaction = connection.BeginTransaction())
    
       //Attempt to do stuff in the database
       //potentially throw an exception
       transaction.Commit();
    

【问题讨论】:

嗨,只是为了澄清“提交”案例。这当然是强制性的,因为 using() 只是调用 Dispose() 方法。如果 Commit 也是自动的,则 Transaction.Dispose 类无法知道它是否应该 Commit 或 Dispose :) 另见***.com/questions/6418992/… 【参考方案1】:

事务类的 Dispose 方法执行回滚,而 Oracle 的类不执行。所以从事务的角度来看,它依赖于实现。

另一方面,连接对象的using 语句要么关闭与数据库的连接,要么在重置连接后将连接返回到池。在任何一种情况下,都应该回滚未完成的事务。这就是为什么异常永远不会留下活动事务的原因。

另外,是的,您应该明确调用Commit()

【讨论】:

会的,我什至通过显式抛出异常测试过一次。 很棒,但是如果您将它用于跨数据库兼容性,它是否适用于 IDbTransaction 的其他实现? @mezoid:提交永远不会自动发生。 @matt:按照设计,他们应该这样做。 @MattHamilton 正如 ssg 所说。我检查了 mysql 的 .net 连接器源,他们也做了同样的事情,如上所示。 RollbackDispose 中被调用! :) 如果您使用的是System.Data.OracleConnection,它不会在 dispose 时回滚。或者至少,对我们来说不是。【参考方案2】:

你必须调用 commit。 using 语句不会为您提交任何内容。

【讨论】:

是的,using 将在退出时调用 Dispose,这将调用 Rollback,而不是 Commit。【参考方案3】:

我相信如果出现了Commit()从未被调用的异常,那么事务会自动回滚。

【讨论】:

是的,这是我的理解。事务一直存在,直到调用提交或连接结束。此时,事务日志实际上会随着更改而更新,或者在连接关闭的情况下回滚(您知道您永远不会从关闭的连接中获得提交;))。

以上是关于如果发生错误,using 语句会回滚数据库事务吗?的主要内容,如果未能解决你的问题,请参考以下文章

对mysql事务提交回滚的错误理解

PG 事务提交与回滚

mysql事务未commit

如果外部事务范围未完成,内部事务范围会回滚吗?

数据库事务

MYSQL事务