据我了解,使用SELECT tl.text
FROM text_lines tl
LEFT JOIN bak_lines bl
ON tl.text = bl.text
WHERE bl.text is null
的“正确”方法是始终在退出TransactionScope
块之前调用transactionScope.Complete();
。像这样:
using
但是,我已经看到代码没有它就可以工作,甚至the answer I've learnt to use it from都将其省略。所以我的问题是,是否必须使用它?
答案 0 :(得分:7)
为进行所以我的问题是,是否必须使用它?
Complete
交易而进行更新时必须使用 COMMIT
。否则,事务管理器将发出ROLLBACK
并撤消所做的更改。
对于像您的示例这样的只读事务,无论有没有Complete
,我都认为没有实质性的区别。在两种情况下,事务管理器发出的COMMIT
或ROLLBACK
具有释放事务持有的锁和资源的相同净效果。
尽管不是必须在只读事务中调用Complete
,但它仍然是IMHO的最佳做法。考虑一下这个可怜的开发人员,他后来在不知不觉中丢失了Complete
的情况下,无意中将数据修改代码添加到了您的事务块中。
答案 1 :(得分:3)
是的,您需要使用它,它是通过TransactionScope类上的Microsoft文档向编译器通知您已成功完成任务的方式:
当您的应用程序完成它希望在事务中执行的所有工作时,您应该只调用一次Complete方法,以通知该事务管理器可以接受提交事务。未能调用此方法将中止事务。
也用于Complete方法:
未能调用此方法将中止事务,因为事务管理器将其解释为系统故障或在事务范围内引发的异常。但是,您还应该注意,调用此方法不能保证事务的落实。这只是一种向交易经理通知您身份的方法。
答案 2 :(得分:0)
基本上using语句在C#编译器的编译时转换为该语句。
TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted })
try
{
//your works
}
finally
{
if (transactionScope != null)
((IDisposable)transactionScope).Dispose();
}
所以这就是C#的全部期望...。您只需要使用TransactionScope进行工作
如果TransactionScope对象最初创建了事务,则事务管理器提交事务的实际工作发生在using块中的最后一行代码之后。如果未创建事务,则每当Transaction对象的所有者调用Commit时,都会进行提交。那时,事务管理器将根据是否在TransactionScope对象上调用了Complete方法,来调用资源管理器并通知他们进行提交或回滚。
调用此方法不能保证事务将被提交。这只是一种向交易经理通知您身份的方法。调用Complete方法后,您将无法再使用Current属性访问环境事务,而尝试执行该操作将导致引发异常。
using语句确保即使发生异常,也将调用TransactionScope对象的Dispose方法。 Dispose方法标记事务作用域的结束。调用此方法后发生的异常可能不会影响事务。此方法还可以将环境事务还原到以前的状态。
如果范围创建了事务,则抛出TransactionAbortedException,并且事务中止。如果事务管理器无法达到Commit决策,则抛出TransactionInDoubtException。如果事务已提交,则不会引发异常。
希望这会为您清除