web-dev-qa-db-ja.com

TransactionScopeを取得して、async / awaitを操作します

async/awaitをサービスバスに統合しようとしています。この例に基づいてSingleThreadSynchronizationContextを実装しました http://blogs.msdn.com/b/pfxteam/archive/2012/01/20/10259049.aspx

そして、TransactionScopeという1つの点を除いて、正常に機能します。 TransactionScopeの中にあるものを待ち、それはTransactionScopeを壊します。

TransactionScopeは、asyncを使用してスレッドに格納するため、await/ThreadStaticAttributeでNiceを再生しないようです。私はこの例外を受け取ります:

「TransactionScopeが正しくネストされていません。」。

タスクをキューに入れる前にTransactionScopeデータを保存し、実行する前に復元しようとしましたが、何も変わっていないようです。そしてTransactionScopeコードは混乱しているので、そこで何が起こっているのかを理解するのは本当に難しいです。

それを機能させる方法はありますか? TransactionScopeに代わるものはありますか?

110
Yann

.NET Framework 4.5.1には、TransactionScopeパラメーターをとる TransactionScopeAsyncFlowOptionの新しいコンストラクター のセットがあります。

MSDNによると、スレッドの継続にわたるトランザクションフローが可能になります。

私の理解では、次のようなコードを記述できるようになっているということです。

// transaction scope
using (var scope = new TransactionScope(... ,
  TransactionScopeAsyncFlowOption.Enabled))
{
  // connection
  using (var connection = new SqlConnection(_connectionString))
  {
    // open connection asynchronously
    await connection.OpenAsync();

    using (var command = connection.CreateCommand())
    {
      command.CommandText = ...;

      // run command asynchronously
      using (var dataReader = await command.ExecuteReaderAsync())
      {
        while (dataReader.Read())
        {
          ...
        }
      }
    }
  }
  scope.Complete();
}
157
ZunTzu

少し遅れて答えましたが、MVC4で同じ問題が発生していました。プロジェクトを右クリックしてプロパティに移動し、プロジェクトを4.5から4.5.1に更新しました。 [アプリケーション]タブを選択し、ターゲットフレームワークを4.5.1に変更し、次のようにトランザクションを使用します。

using (AccountServiceClient client = new AccountServiceClient())
using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
}
7
Atul Chaudhary

DependentTransactionTransaction.DependentClone() メソッドによって作成されたものを使用できます。

static void Main(string[] args)
{
  // ...

  for (int i = 0; i < 10; i++)
  {

    var dtx = Transaction.Current.DependentClone(
        DependentCloneOption.BlockCommitUntilComplete);

    tasks[i] = TestStuff(dtx);
  }

  //...
}


static async Task TestStuff(DependentTransaction dtx)
{
    using (var ts = new TransactionScope(dtx))
    {
        // do transactional stuff

        ts.Complete();
    }
    dtx.Complete();
}

DependentTransactionによる並行性の管理

http://adamprescott.net/2012/10/04/transactionscope-in​​-multi-threaded-applications/

6
maximpa