2010-01-04 58 views
10

TransactionScope期望按如下方式调用其Complete方法。否则,交易将不会被提交。为什么TransactionScope不会成功?

using(TransactionScope scope = new TransactionScope()) 
{ 
    /* Perform transactional work here */ 

    scope.Complete(); 
} 

那么假设成功的实现更合适吗?这意味着在标准情况下(成功)将需要更少的代码。

在异常或呼叫给方法的情况下为“回滚”(该方法目前不存在),例如事务可以被回滚。

using(TransactionScope scope = new TransactionScope()) 
{ 
    /* Perform transactional work here */ 

    if(problemOccurred) 
    { 
     scope.Rollback(); 
    } 
} 

请注意,只有在问题未导致异常的情况下,才会需要problemOccurred标志。在这种情况下,回滚将自动执行。

我感兴趣的获得进一步了解为什么使用此实施。

更新:迄今为止的一些答案认为,如果使用我描述的实现,则需要try-catch块。不是这种情况。当在使用块中未处理异常时,事务自动回滚。现有的实施和我描述的都是这种情况。有关更多详细信息,请参阅“完成交易范围”部分here

更新2:我终于明白发生了什么的答案被解释。这不是一种语言结构,它可以用语言设计者认为合适的任何方式进行解释 - 它是IDisposable模式的实现。如果没有调用完成Dispose方法内的代码,则不知道它是否被调用,因为正在成功执行using块中的代码或发生异常。我想象的事物和回滚都是关键字。

transaction 
{ 
    /* Perform transactional work here */ 

    if(problemOccurred) 
    { 
     rollback; 
    } 
} 

如果事务选项需要传递给TransactionScope,这当然会出现问题。

+3

为什么不是我的评论自动添加当我改变页面,我不应该单击[添加评论] ... – cjk 2010-01-04 13:20:37

+1

从更新 - * *机制,通过该交易在例外的脸回滚是你在不调用Commit的情况下到达使用块的末尾。即该行为取决于您要删除的确切功能。 – 2010-01-04 14:12:55

+0

你的“更新”是指当前的游戏状态 - 如果TransactionScope假定成功,你会改变这种情况。 – 2010-01-04 14:15:01

回答

14

这意味着你不需要把一个手动尝试/最后(或捕捉)块(可能带有“成功”标志)的失败案例。尝试重写上面的代码回滚的错误,看看它是多么混乱......

基本上正常期望的行为是如果达到,没有例外块结束时仅提交。实现这一目标的最简单方法是在块的末尾放置一个方法调用来表示成功。

+0

我不认为需要尝试块 - 请参阅我在回答中的评论... http://stackoverflow.com/questions/1999461/why-doesnt-transactionscope-assume-success/1999475#1999475 你同意吗? – 2010-01-04 13:51:23

+1

不,因为你提出*改变*这种行为。 *当前*由于您所抱怨的行为,您不需要try/catch块 - 除非您明确提交,否则将会失败。 – 2010-01-04 14:14:20

4

如果选择了其他实现,那么人们会问这个相反的问题!

尽管如此,在一个旨在保护部分或不正确更新的机制中的默认行为必然是而不是要提交,不是吗?

15

这样一来,每一笔交易是这样的:

using(TransactionScope scope = new TransactionScope()) 
{ 
    try 
    { 
    /* Perform transactional work here */ 
    } 
    catch (Exception) 
    { 
    scope.Rollback(); 
    throw; 
    } 
} 

这是更多的代码。

编辑:

其他的都是有风险或不良作风。 你必须绝对确保提交时有没有任何错误。当离开使用块时,您不知道是否因为抛出异常而抛弃它,或者因为刚到达它的末尾。当你拨打Complete时,你知道。

的事务块语法已经是你可以做的最简单。只需在没有任何特殊错误处理的情况下执行事务,并在最后提交它。出现任何错误时,您不必关心和回滚。考虑一下,几乎每一行代码都会抛出异常(例如,NullReference,Overflows,InvalidOperation等)。那么比这更容易的是什么?

+1

如果使用scope.Complete()方法,如果出现回滚,何时会发生回滚? – DOK 2010-01-04 13:30:54

+1

TransactionScope使用块内的异常会自动回滚事务。这里除了MSDN以外。 “无法调用此方法会中止事务,因为事务管理器将此解释为系统故障,或等同于事务范围内引发的异常。“ 你try块是多余的。 – 2010-01-04 13:45:41

+0

这里是除的链接。 http://msdn.microsoft.com/en-us/library/ms172152.aspx – 2010-01-04 13:55:26

3

我觉得写的代码量成功的,因为@乔恩飞碟双向说,少(少丑)目前的方式。从一个交易点,但是,我想你会悲观,并认为除非成功是明确指出,你会回滚。在我看来,提交错误交易是一个非常糟糕的问题,而不是由于代码错误而意外无法成功执行交易。

相关问题