1

大規模なアプリケーションでNhibernateとTransactionScopeを使用しています。 アプリケーションは3つのデータベースを変更し、それらの間で分散トランザクションをサポートすることになっています。 これは私が私が照会またはdistribuitedトランザクション内のデータベースにいくつかのSQLを実行するたびに呼び出すコードです:nhibernateとトランザクションスコープのトランザクションが自発的に中断されました

IDbConnection connection = new SqlConnection(connectionString); 
connection.Open(); 
ISession session = SessionFactory.OpenSession(connection); 

をそして、これは、必要な操作が

IDbConnection sqlConnection = session.Connection; 
if (sqlConnection != null && sqlConnection.State == ConnectionState.Open) 
    sqlConnection.Close(); 
session.Dispose(); 

を実行した後、いつでも呼び出したコードです

私はまた、この内のコードをラップ更新、挿入、削除のステートメントを実行する場合:

using (var transaction = session.BeginTransaction()) 
{ //code here 

transaction.Commit();} 

を、私はこれはかなり標準だと思いますもの。 今...私はこの使用してブロック内のこれらの操作を実行します。

using (TransactionScope scope = new TransactionScope()) 
{ 
//code here 
scope.Complete(); 
} 

私の問題は、それが開始された後、私の取引が散発的​​に約6秒で中止されていることである(Transaction.Current.TransactionInformation.Statusは中止となります) 。

これは私のDistribuitedトランザクションコーディネータからのトレースです:

pid=6296  ;tid=13300  ;time=04/17/2012-19:34:29.430 ;seq=1   ;eventid=TRANSACTION_MANAGER_STARTED_2   ;;"TM Identifier='(null)           '" ;"MS DTC started with the following settings: Security Configuration (OFF = 0 and ON = 1): Network Administration of Transactions = 0, Network Clients = 1, Inbound Transactions = 1, Outbound Transactions = 1, Transaction Internet Protocol (TIP) = 0, XA Transactions = 0, MSDTC RPC Security = Mutual Authentication Required, Account = NT AUTHORITY\NetworkService, Firewall Exclusion = 0, Transaction Bridge Installed = 0, Filtering duplicate events = 1." 
pid=6296  ;tid=13300  ;time=04/17/2012-19:34:29.430 ;seq=2   ;eventid=TRACE_SETTINGS       ;;"TM Identifier='(null)           '" ;"Trace Configuration (OFF = 0 and ON = 1): Tracing Of DTC = 1, Tracing Of Transactions = 1, Tracing Of Aborted Transactions = 1, Tracing Of Long-Lived Transactions = 1, Tracing Of All Transactions = 0, Max Limit on Memory Buffers = 0." 
pid=6296  ;tid=11372  ;time=04/17/2012-19:35:19.496 ;seq=3   ;eventid=CHECKPOINTING_STOPPED     ;;"TM Identifier='(null)           '" ;"MSDTC is suspending the checkpointing of transactions due to lack of activity" 
pid=6296  ;tid=11372  ;time=04/17/2012-19:35:19.496 ;seq=4   ;eventid=TRACING_STOPPED       ;;"TM Identifier='(null)           '" ;"MSDTC is suspending the tracing of long - lived transactions due to lack of activity" 
pid=6296  ;tid=10520  ;time=04/17/2012-19:36:31.191 ;seq=5   ;eventid=TRACING_STARTED       ;;"TM Identifier='(null)           '" ;"MSDTC is resuming the tracing of long - lived transactions" 
pid=6296  ;tid=10520  ;time=04/17/2012-19:36:31.212 ;seq=6   ;eventid=TRANSACTION_BEGUN      ;tx_guid=5c61419a-eec2-49c1-aaa1-007645a72e32  ;"TM Identifier='(null)           '" ;"transaction has begun, description :'user_transaction'" 
pid=6296  ;tid=10520  ;time=04/17/2012-19:36:31.212 ;seq=7   ;eventid=RM_ENLISTED_IN_TRANSACTION    ;tx_guid=5c61419a-eec2-49c1-aaa1-007645a72e32  ;"TM Identifier='(null)           '" ;"resource manager #1001 enlisted as transaction enlistment #1. RM guid = 'b9290b2d-9e1d-43ed-a5f3-e417f9b17906'" 
pid=6296  ;tid=8016  ;time=04/17/2012-19:36:36.141 ;seq=8   ;eventid=RECEIVED_ABORT_REQUEST_FROM_BEGINNER  ;tx_guid=5c61419a-eec2-49c1-aaa1-007645a72e32  ;"TM Identifier='(null)           '" ;"received request to abort the transaction from beginner" 
pid=6296  ;tid=8016  ;time=04/17/2012-19:36:36.141 ;seq=9   ;eventid=TRANSACTION_ABORTING      ;tx_guid=5c61419a-eec2-49c1-aaa1-007645a72e32  ;"TM Identifier='(null)           '" ;"transaction is aborting" 
pid=6296  ;tid=8016  ;time=04/17/2012-19:36:36.141 ;seq=10   ;eventid=RM_ISSUED_ABORT       ;tx_guid=5c61419a-eec2-49c1-aaa1-007645a72e32  ;"TM Identifier='(null)           '" ;"abort request issued to resource manager #1001 for transaction enlistment #1" 
pid=6296  ;tid=8016  ;time=04/17/2012-19:36:36.219 ;seq=11   ;eventid=RM_ACKNOWLEDGED_ABORT     ;tx_guid=5c61419a-eec2-49c1-aaa1-007645a72e32  ;"TM Identifier='(null)           '" ;"received acknowledgement of abort request from the resource manager #1001 for transaction enlistment #1" 
pid=6296  ;tid=8016  ;time=04/17/2012-19:36:36.219 ;seq=12   ;eventid=TRANSACTION_ABORTED      ;tx_guid=5c61419a-eec2-49c1-aaa1-007645a72e32  ;"TM Identifier='(null)           '" ;"transaction has been aborted" 

誰もが私が間違っているの何を知っていますし、どのように私が中止されることから、私のトランザクションを保つことができますか? ありがとうございます。

アップデート1: 私は2つのセッションを開くとtwoardsデータベースの2すぐのTransactionScopeオブジェクトをインスタンス化した後、私は上記のエラーを取得します。 1つのデータベースへの私だけがセッションをオープンして、私は、私は次のエラーを取得する、後にセッションtwoards他人のいずれかを開きます。

The PROMOTE TRANSACTION request failed because there is no local transaction active. 

connection.Openは()に到達すると、接続がの方に開いているときに、この問題が発生しました2番目のデータベース。

+0

トランザクションの分離レベルはどの程度ですか?私はそれが設定されて表示されませんでした。 – CrazyCoderz

+0

実際に分散トランザクションを使用することもできます。TransactionScope _scope = new TransactionScope(TransactionScopeOption.Required、new TransactionOptions {IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted}); – CrazyCoderz

答えて

1

このシナリオでこのコードをテストしていない複数のデータベースに役立つかどうかは分かりません。ここでは、トランザクションの処理方法の例を示します。

public interface ISessionManager : IDisposable 
{ 
    ISession Session { get; set; } 
    ISession GetSession(); 
} 

public class SessionManager : ISessionManager 
{ 
    private readonly ISessionFactory _sessionFactory; 
    private TransactionScope _scope; 
    public SessionManager(ISessionFactory sessionFactory) 
    { 
     _sessionFactory = sessionFactory; 
    } 

    #region ISessionManager Members 

    public ISession Session { get; set; } 

    public ISession GetSession() 
    { 
     if (Session == null) 
     { 
      Session = _sessionFactory.OpenSession(); 
      if (!CurrentSessionContext.HasBind(_sessionFactory)) 
      { 
       _scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions {IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted}); 
       Session.BeginTransaction(IsolationLevel.ReadCommitted); 
       CurrentSessionContext.Bind(Session); 
      } 
     } 

     Session = _sessionFactory.GetCurrentSession(); 
     Session.FlushMode = FlushMode.Never; 
     return Session; 
    } 


    public void Dispose() 
    { 
     if (CurrentSessionContext.HasBind(_sessionFactory)) 
     { 
      CurrentSessionContext.Unbind(_sessionFactory); 
     } 
     try 
     { 
      Session.Transaction.Commit(); 
      _scope.Complete(); 
      _scope.Dispose(); 
      Session.Flush(); 
     } 
     catch (Exception) 
     { 
      Session.Transaction.Rollback(); 
      throw; 
     } 
     finally 
     { 
      Session.Close(); 
      Session.Dispose(); 
     } 
    } 

    #endregion 
} 
関連する問題