是否需要显式事务回滚?
许多例子都主张显式回滚数据库事务,大致如下:
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();
}
当发生异常时,我只是依赖于未提交的事务的隐式回滚。
依赖这种隐式行为有什么问题吗?有人有一个令人信服的理由为什么我不应该这样做吗?
Many examples out there advocate explicit rollback of database transactions, along the lines of:
using (var transaction = ...)
{
try
{
// do some reading and/or writing here
transaction.Commit();
}
catch (SqlException ex)
{
// explicit rollback
transaction.Rollback();
}
}
However, I tend to do this:
using (var transaction = ...)
{
// do some reading and/or writing here
transaction.Commit();
}
When an exception occurs, I'm just relying on the implicit rolling back of transactions that aren't committed.
Is there any problem relying on this implicit behavior? Does anyone have a convincing reason why I shouldn't be doing it this way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
不,它不是特别需要的,但是我可以想到为什么它可能是一个好主意的两个原因:
有些人可能会认为使用
transaction.Rollback()
可以更清楚地表明在什么情况下事务不会发生尽心尽力。在处理事务时,重要的是要认识到某些锁只有在事务回滚或提交时才会被释放。如果您使用
using
语句,则在处理事务时事务将回滚,但是如果由于某种原因您需要在using
内部进行一些错误处理块,在执行复杂/耗时的错误处理之前回滚事务(删除锁)可能是有利的。No, its not specifically needed, however I can think of 2 reasons why it might be a good idea:
Some might argue that using
transaction.Rollback()
makes it clearer under what circumstances the transaction will not be committed.When dealing with transactions it is important to realise the certain locks will only be released when the transaction is rolled back or committed. If you are using the
using
statement then the transaction will be rolled back when the transaction is disposed of, however if for some reason you need to do some error handling inside theusing
block, it may be advantageous to rollback the transaction (removing the locks) before performing complex / time consuming error handling.大多数正确编写的 ADO.NET 连接将回滚未显式提交的事务。所以这并不是绝对必要的。
我看到显式
Rollback()
的主要好处是能够在那里设置断点,然后检查连接或数据库以查看发生了什么。正在进行中。对于代码的未来维护者来说,在不同的执行路径下会发生什么也更清楚。Most properly written ADO.NET connection will rollback transactions not explicitly committed. So it's not strictly necessary.
The main benefit I see of an explicit
Rollback()
call it the ability to set a breakpoint there and then inspect either the connection or the database to see what was going on. It's also clearer to future maintainers of the code what happens under different execution paths.我发现您的使用存在两个问题:
I see two problems with your usage:
我想可以回答说,第一种方法对于维护代码的人来说更具可读性。编码的明确性质使得目标清晰且快速。虽然隐式回滚对于您以及可能对事务处理有更多了解的任何人来说都是清楚的,但对其他人来说可能并不清楚。也就是说,一些评论很快就能纠正这个问题。唯一的问题是隐式回滚是否不是对象的已记录功能。
因此,我想说,如果您对操作进行评论并且可以依赖隐式操作,那么就没有充分的理由采用显式方法。
I guess it could be answered that the first approach is more readable for someone maintaining your code. The explicit nature of the coding makes the objectives clear and quickly. While the implicit rollback is clear to you, and probably anyone who has more than a passing knowledge of the transaction handling, it may not be to others. That said, a few comments would quickly rectify that. The only concern is if the implicit rollback is not a documented feature of the object.
So, I'd say, providing you comment the operation and you can rely on the implicit action, then there's not a good reason to go for the explicit approach.
只要事务在 using() 块中完全独立,就可以开始了。但是,如果某人从调用者那里传递了现有的事务对象,那么问题可能而且确实会出现。但那是不同的场景...
As long as the transaction is totally self-contained in the using() block, you are good to go. Problems can and do arise, though, if someone if you are passed an existing transaction object from a caller. But that's a different scenario...