TransactionScopeOption - 必需或RequiresNew

Abh*_*tee 14 .net constructor transactions transactionscope

我目前对TransactionScope对象的构造函数感到困惑.

假设我的网站用户可以订购产品.在提交请求时,我会对剩余的当前数量进行验证,如果仍然大于零,我会执行请求.然后,在结束时,我减少当前剩余的数量.

整个过程使用.NET transactionScope进行事务处理.

在阅读了几篇关于.NET transactionScope对象的文章之后,我现在对TransactionScopeOption的值有点困惑,它用于transactionScope的构造函数.

以下哪一种更适合上述情况:

public void ProcessRequest()  
 {  
     TransactionOptions transactionOptions = new TransactionOptions();  
     transactionOptions.IsolationLevel = IsolationLevel.Serializable;  
     using (TransactionScope currentScope = new TransactionScope(TransactionScopeOption.RequiresNew, transactionOptions)) {  
      // DB Query to verify if quantity is still greater than zero  
      // DB Query to request and decrement quantity 
      currentScope.Complete();
     }  
 }  
Run Code Online (Sandbox Code Playgroud)

要么

public void ProcessRequest()  
 {  
     TransactionOptions transactionOptions = new TransactionOptions();  
     transactionOptions.IsolationLevel = IsolationLevel.Serializable;  
     using (TransactionScope currentScope = new TransactionScope(TransactionScopeOption.Required, transactionOptions)) {  
      // DB Query to verify if quantity is still greater than zero  
      // DB Query to request and decrement quantity 
      currentScope.Complete();
     }  
 }  
Run Code Online (Sandbox Code Playgroud)

请注意,上面只是对我实际问题的过度简化.我只对在这种情况下知道TransactionScopeOption(RequiresNewRequired)的正确值感兴趣.

感谢回复.

Jef*_*nal 15

如果另一个方法ProcessRequest 在另一个事务中调用,这取决于你想要发生什么:

public void SomeOtherMethod() {
    using (TransactionScope ts = new TrasansctionScope()) {
        // Another DB action
        ProcessRequest();
        // Yet another DB action
    }
}
Run Code Online (Sandbox Code Playgroud)

如果要ProcessRequest使用创建的事务SomeOtherMethod,请使用TransactionScope.Required.这是默认值(当您调用它时,它仍会创建一个事务,而不会在调用堆栈中创建另一个事务范围).

如果您希望它强制此方法始终使用自己的(新)事务,请使用TransactionScope,RequiresNew.

  • 绝对 - 否则,你(无意中)暗示ProcessRequest有一些特殊的东西要求它使用自己的事务. (2认同)

Gqq*_*big 8

我知道你的方法不会在另一个事务中被调用.但万一会这样,这就是你的选择TransactionScopeOption.

如果ProcessRequest写入数据库的内容不能被任何调用者推翻,则使用RequiresNew,这将启动与调用者创建的事务(如果有)并行的新事务,并且新事务不会由调用者以任何方式管理.最好不要嵌套事务,使用现有事务或创建新事务.交易不是嵌套的!

如果可以推翻ProcessRequest写入数据库的内容,请使用Required.但是,此选项不透明; 对ProcessRequest的调用者必须知道ProcessRequest可能会回滚,因为如果被调用者回滚环境事务,则调用者不能执行任何sql操作,否则异常"该操作对事务状态无效".将被抛出.最好System.Transactions.Transaction.Current.TransactionInformation.Status在运行任何查询之前始终检查,因为您不知道是否有任何被调用者偷偷创建了一个事务并将其回滚.

您可能会发现下表很有用. 在此输入图像描述