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


83

我在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();
    }
}

3
嗨,只是为了澄清“提交”的情况。当然这是强制性的,因为using(){}仅调用Dispose()方法。Transaction.Dispose类不知道它是否应该提交,或者该提交是否也是自动处理的:)
Manitra Andriamitondra 2010年

Answers:


104

事务类的Dispose方法执行回滚,而Oracle的类则不执行。因此,从事务的角度来看,它取决于实现。

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

另外,是的,您应该Commit()显式调用。


我什至会通过显式抛出异常来测试一次。
Pawel Krakowiak

1
真棒,但它对于IDbTransaction的其他实现的工作,如果你使用它进行跨数据库的兼容性?
马特·汉密尔顿

4
@mezoid:提交永远不会自动发生。@matt:他们应该是设计使然。
Sedat Kapanoglu,2009年

1
@MattHamilton就像ssg所说。我检查了MySQL的.net连接器源,它们的功能也与上面所示相同。Rollback被呼入Dispose!:)
nawfal

1
如果您使用System.Data.OracleConnection,则不会在处理时回滚。至少,对我们而言,不是。
Medinoc

20

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


5
是的,使用将在退出时调用“处置”,这将调用“回滚”而不是“提交”。
敬畏

4

我认为,如果存在Commit()从未被调用的异常,那么事务将自动回滚。


是的,这是我的理解。事务一直存在,直到调用被调用或连接结束为止。到那时,事务日志实际上会随着更改而更新,或者在关闭连接的情况下回滚(您知道您永远不会从关闭的连接中获得提交;)。
2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.