[c#] TransactionScope를 사용하여 비동기 / 대기

나는 통합하기 위해 노력하고있어 async/ await우리의 서비스 버스로. SingleThreadSynchronizationContext이 예제를 기반으로 http://blogs.msdn.com/b/pfxteam/archive/2012/01/20/10259049.aspx를 구현했습니다 .

그리고 한 가지를 제외하고는 잘 작동합니다 TransactionScope. 나는 내부의 물건을 기다리고 TransactionScope있으며 TransactionScope.

TransactionScopeasync/를 await사용하여 스레드에 항목을 저장하기 때문에 / 와 잘 어울리지 않는 것 같습니다 ThreadStaticAttribute. 이 예외가 발생합니다.

“TransactionScope가 잘못 중첩되었습니다.”

TransactionScope작업을 대기열에 추가하기 전에 데이터 를 저장 하고 실행하기 전에 복원하려고했지만 아무것도 변경되지 않는 것 같습니다. 그리고 TransactionScope코드는 엉망이어서 무슨 일이 일어나고 있는지 이해하기가 정말 어렵습니다.

작동하도록하는 방법이 있습니까? 에 대한 대안이 TransactionScope있습니까?



답변

.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();
}


답변

답변에 조금 늦었지만 MVC4에서 동일한 문제가 발생했으며 프로젝트 이동 속성을 마우스 오른쪽 버튼으로 클릭하여 프로젝트를 4.5에서 4.5.1로 업데이트했습니다. 애플리케이션 탭 변경 대상 프레임 워크를 4.5.1로 선택하고 다음과 같이 트랜잭션을 사용합니다.

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


답변

Transaction.DependentClone () 메서드로 만든 DependentTransaction 을 사용할 수 있습니다 .

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/


답변