1

我正在浏览一段代码并遇到以下内容:

 using(var transactionScope = new TransactionScope(TransactionScopeOption.Required, new TransactionScopeOptions { IsolationLevel = IsolationLevel.Snapshot })
    {
        List<Task> tasks = new List<Task>();
        try
        {
            // Perform some database operation to read data (These operations are happening with a transaction scope having scopeoption as "Required" and isolationlevel as "ReadCommitted")
           // Filter the data
           // At this point the code already has a reference to a WCF duplex callback
           // Create a List<Task> and a
           foreach(var data in List<SomeData>)
           {
               var task = Task.Factory.StartNew(() => {
                  **(WCF Duplex Callback Instance).Process(data);**
           });
           tasks.Add(task);
         }
       }
       catch(Exception ex)
       {
         // Log exception details
       }

       transactionScope.Complete();

    }

try
{
   Task.WaitAll(tasks);
}
catch(AggregateException ae)
{
    ae.Handle( ex => {
         // log exception details
         return true;
    });
}

问题:

  1. 父事务隔离级别为“快照”,而内部数据库读取使用“ReadCommitted”。实际的事务隔离级别是什么?

  2. 假设有两个任务。任务 1 处理得很好,并在回调通道上发送到 WCF 客户端。但任务 2 引发了异常。我猜此时在父事务范围内执行的所有活动都应该回滚。但我不确定回滚一组已经通过 WCF 回调通道发送到客户端的数据意味着什么。

4

1 回答 1

2

1)这取决于,如果你的意思是嵌套的 TransactionScope,那么根据 MSDN,你不能让它们以不同的隔离级别嵌套:

使用嵌套的 TransactionScope 对象时,如果所有嵌套的范围都想加入环境事务,则必须配置为使用完全相同的隔离级别。如果嵌套的 TransactionScope 对象尝试加入环境事务但它指定了不同的隔离级别,则会引发 ArgumentException

但是,如果您使用一些存储过程、函数或仅运行原始 SQL,您可以显式更改隔离级别,并且它会为该连接保持设置,直到再次显式更改。但请注意,它不会传播回 TransactionScope 对象。

2)这意味着通过资源管理器完成的所有更改都将被回滚。当然,如果您只是查询数据库并通过通道将结果传回,则无需回滚,但如果您更新数据库,则在这种情况下应该回滚更改。

希望能帮助到你!

于 2013-06-10T15:36:06.497 回答