如果发生错误,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 连接器源,他们也做了同样的事情,如上所示。Rollback
在Dispose
中被调用! :)
如果您使用的是System.Data.OracleConnection
,它不会在 dispose 时回滚。或者至少,对我们来说不是。【参考方案2】:
你必须调用 commit。 using 语句不会为您提交任何内容。
【讨论】:
是的,using 将在退出时调用 Dispose,这将调用 Rollback,而不是 Commit。【参考方案3】:我相信如果出现了Commit()
从未被调用的异常,那么事务会自动回滚。
【讨论】:
是的,这是我的理解。事务一直存在,直到调用提交或连接结束。此时,事务日志实际上会随着更改而更新,或者在连接关闭的情况下回滚(您知道您永远不会从关闭的连接中获得提交;))。以上是关于如果发生错误,using 语句会回滚数据库事务吗?的主要内容,如果未能解决你的问题,请参考以下文章