2011-07-19 16 views
3

私はいくつかの方法を持っています。SQL Serverといくつかのビジネスロジックを呼び出すことで、独自の価値を生み出すことができます。これらのメソッドは、すべての親メソッド内に含まれています。なぜこのトランザクションは分離されていませんか?

GenerateUniqueValue() 
{ 
    //1. Call to db for last value 
    //2. Business logic to create new value 
    //3. Update db with new value created 
} 

私はすなわち、GenerateUniqueValueへの呼び出しを単離することにしたい - 2つのクライアントが同時にそれを呼び出す際に、第2のクライアントが終了するの最初のを待たなければなりません。

元々、私は自分のサービスをシングルトンにしました。しかし、私はロードバランシングを含む将来の変更を予期しなければならないので、シングルトンのアプローチが間違っていると思います。

[ServiceBehavior(TransactionIsolationLevel = IsolationLevel.Serializable, TransactionTimeout = "00:00:30")] 

そして、と私GenerateUniqueValue::次の私のサービスを飾ることによって、トランザクションのアプローチをとることに決めた

[OperationBehavior(TransactionScopeRequired = true)] 

問題があるというエラーでサービスメソッドの結果への同時ヒットのテスト:

private static void Main(string[] args) 
    { 

     List<Client> clients = new List<Client>(); 
     for (int i = 1; i < 20; i++) 
     { 
      clients.Add(new Client()); 
     } 

     foreach (var client in clients) 
     { 
      Thread thread = new Thread(new ThreadStart(client.GenerateUniqueValue)); 
      thread.Start(); 
     } 

     Console.ReadLine(); 
    } 
:ここ

"System.ServiceModel.ProtocolException: The transaction under which this method call was executing was asynchronously aborted."

は私のクライアントのテストコードです

トランザクションが分離されていると想定されている場合、メソッドを呼び出す複数のスレッドが何故衝突しているのですか?

答えて

2

トランザクションは、複数のアクションを1つのアトミックアクションとして扱うためのものです。したがって、2番目のスレッドを最初のスレッドの完了まで待機させたい場合は、トランザクションではなく並行処理を処理する必要があります。

System.ServiceModel.ServiceBehaviorAttribute.ConcurrencyMode属性にSingleまたはReentrant同時実行モードを使用してみてください。私はそれがあなたが期待しているものだと思います。

[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Reentrant)] 

私はIsolationLevel.Serializableは、揮発性データにアクセスするために、第2のスレッドを可能にするが、それはそれを変更することはできないだろうので、あなたは例外だと思います。あなたはこの隔離レベルでは許可されていない変更操作を行っています。

関連する問題