许多例子都提倡明确回滚数据库事务,其中包括:
using (var transaction = ...)
{
try
{
// do some reading and/or writing here
transaction.Commit();
}
catch (SqlException ex)
{
// explicit rollback
transaction.Rollback();
}
}
但是,我倾向于这样做:
using (var transaction = ...)
{
// do some reading and/or writing here
transaction.Commit();
}
当发生异常时,我只是依赖于未提交的事务的隐式回滚。
是否存在依赖此隐式行为的问题?有没有人有一个令人信服的理由为什么我不应该这样做?
答案 0 :(得分:14)
不,它并非特别需要,但我可以想到它可能是一个好主意的两个原因:
有些人可能会争辩说,使用transaction.Rollback()
可以在什么情况下更清楚地提交交易。
在处理事务时,重要的是要意识到某些锁只会在事务回滚或提交时释放。如果您正在使用using
语句,则事务将在事务处理时回滚,但是如果由于某种原因您需要在using
块内部进行一些错误处理,则可能是有利的在执行复杂/耗时的错误处理之前回滚事务(删除锁)。
答案 1 :(得分:4)
我发现您的使用存在两个问题:
答案 2 :(得分:1)
我想可以回答第一种方法对于维护代码的人来说更具可读性。编码的明确性使得目标明确且快速。虽然隐式回滚对您来说很明显,并且可能是任何拥有超过事务处理知识的人,但它可能不属于其他人。也就是说,一些评论很快就会纠正这一点。唯一的问题是隐式回滚是否是对象的文档特征。
所以,我会说,如果您对操作发表评论,并且可以依赖隐式操作,那么就没有充分的理由去采用明确的方法。
答案 3 :(得分:1)
大多数正确编写的ADO.NET连接都会回滚未显式提交的事务。所以这不是绝对必要的。
我看到显式Rollback()
的主要好处是它能够在那里设置断点,然后检查连接或数据库以查看发生了什么。对于未来的代码维护者来说,在不同的执行路径下发生的事情也更加清晰。
答案 4 :(得分:0)
只要事务在using()块中完全自包含,你就可以了。但是,如果有人从调用方传递现有的事务对象,则可能会出现问题。但那是另一种情况......