如果外部事务范围未完成,内部事务范围会回滚吗?
Posted
技术标签:
【中文标题】如果外部事务范围未完成,内部事务范围会回滚吗?【英文标题】:Will an inner transaction scope roll back if the outer transaction scope doesn't complete? 【发布时间】:2011-05-28 17:29:09 【问题描述】:我有两个事务范围,一个在另一个范围内。我很想知道内部事务范围在提交后是否会回滚,而外部事务范围没有完成。
【问题讨论】:
各种TransactionScopeOption
选择的很好解释;终于有道理了:docs.microsoft.com/en-us/previous-versions/…
【参考方案1】:
这取决于您启动嵌套事务范围的范围选项。
如果你使用默认选项TransactionScopeOption.Required
,那么嵌套作用域将与外部作用域在同一个事务中登记,因此当外部作用域回滚时,内部作用域也将被回滚,即使它调用了@987654322 @。
但是,如果您使用TransactionScopeOption.RequiresNew
,则嵌套范围将开始自己的事务并与外部范围分开完成,因此即使外部范围回滚,它也不会回滚。
如果您使用TransactionScopeOption.Suppress
,则嵌套范围将不参与外部事务,并将以非事务方式完成,因此不构成外部事务回滚时将回滚的工作的一部分。
【讨论】:
完美答案:) 如果将两个 Suppress 作用域嵌套在第三个外部作用域下怎么办?我是否应该在两个内部 Suppress 范围上调用 complete,这会完全干扰外部父范围吗?【参考方案2】:由于它们是嵌套的,内部事务将回滚。
这不是全部,取决于您如何创建嵌套事务,但默认情况下,它会回滚。
This article 深入了解TransactionScope
,应该会回答您的大部分问题。
分发与否无关紧要。
【讨论】:
@Frantisek 提到了分布式事务。我怎么知道我在使用分布式事务? 我想我错了。使用 TransactionScope,您可能不需要 dtc 来让它工作。阅读此msdn.microsoft.com/en-us/library/ms172152(v=vs.90).aspx:“虽然嵌套范围可以加入根范围的环境事务,但在嵌套范围内调用 Complete 对根范围没有影响。只有从根范围到最后一个嵌套范围的所有范围投票提交交易,交易是否会提交。” 我相信您知道这一点,但是在谈到 TransactionScope 时,术语“内部事务”和“嵌套事务”在恕我直言是不合适的,因为实际上没有嵌套事务,而只是嵌套了 TransactionScope。如果您选择 TransactionScopeOption.Required 它只是 1 个大事务,而使用 TransactionScopeOption.RequiresNew 则有 2 个完全独立的事务,但在(封闭的)嵌套事务的意义上它们不是嵌套的。【参考方案3】:是的,你可以参考下面的代码。如果内部事务抛出错误,则以下代码将回滚外部事务范围,反之亦然。
public bool rootMethod()
using (var transaction = new(TransactionScopeOption.RequiresNew))
try
// your code here
SomeController someController = new SomeController();
var responseFromChildMethod = someController.childMethodWithTxn();
// your logic here
transaction.Complete();
return true;
catch(Exception ex)
transaction.Dispose();
return false;
SomeController.cs
public bool childMethodWithTxn()
using(var newTransaction = new TransactionScope())
try
//your code here
newTransaction.Complete();
return true;
catch(Exception ex)
newTransaction.Dispose();
return false;
【讨论】:
如果 root 或 child 捕获异常,这将回滚以上是关于如果外部事务范围未完成,内部事务范围会回滚吗?的主要内容,如果未能解决你的问题,请参考以下文章