我了解隐式回滚(通常在异常发生并调用Dispose时发生)并不保证适用于所有提供程序。然而,许多示例使用以下语法:
using (DbTransactio txn = cnctn.BeginTransaction())
有什么原因吗?
我了解隐式回滚(通常在异常发生并调用Dispose时发生)并不保证适用于所有提供程序。然而,许多示例使用以下语法:
using (DbTransactio txn = cnctn.BeginTransaction())
using(var tran = conn.BeginTransaction()) {
try {
// do stuff...
tran.Commit();
} catch {
tran.Rollback();
throw;
}
}
TransactionScope
情况下,“Dispose()
未标记为已完成”是发出回滚信号的预期方式。using(var tran = new TransactionScope()) {
// do stuff...
tran.Complete();
}
DbTransactio txn = cnctn.BeginTransaction();
// do something which throws an exception
txn.Commit();
事务不会回滚,直到垃圾收集器决定收集事务对象(请注意,只有实现 IDisposable
接口的类遵循 dispose pattern 才能起作用)。
当然,您也可以这样做:
DbTransaction txn = cnctn.BeginTransaction();
try
{
// do something which throws an exception
txn.Commit();
}
finally
{
txn.Dispose();
}
但这不够易读。
using (var txn = cnctn.BeginTransaction())
{
// do something which throws an exception
txn.Commit();
}
编辑:
我理解隐式回滚(通常在发生异常并调用Dispose时发生)不能保证所有提供程序都支持。
我没有见过任何一个不支持它的提供程序。由于 IDbTransaction继承了IDisposable
,因此所有实现都应该使用Dispose()
来回滚事务。
using
,则无需显式调用Rollback
。在我的看法中,使用带有Commit()
的using
块可以使代码更加清晰。 - jgauffin
Dispose()
,因为它是IDisposable
。我同意在这种情况下,我更喜欢显式的Rollback()
,就像我的例子一样。但这是 除了Dispose()
之外的补充。 - Marc Gravell