2010-06-17 54 views
0

我正在使用NHibernate訪問使用InnoDB表的MySQL數據庫。我知道InnoDB不支持嵌套事務,但我一直認爲事情會更簡單,如果它。NHibernate,MySQL,InnoDB和嵌套事務

看看這個方法吧.. SessionManager會爲每個線程打開一個新的會話。如果我沒有存儲這個事務,它以前會在開啓一個新的時候被mysql自動提交。

這是一個醜陋的解決方法,或唯一的方法?你有更好的方法來做到這一點?

protected override void DoCommand(ICommand command) 
{ 
    // Open session and/or transaction if necessary 
    var repoCommand = command as RepositoryCommand; 
    if (repoCommand != null) 
    { 
     foreach (Type type in repoCommand.PersistenceTypes) 
     { 
      if (!_sessions.ContainsKey(type)) 
      { 
       var session = SessionManager.GetSession(type); 
       _sessions[type] = session; 

       // Several types might share the same session, 
       // so we'll only create one transaction 
       // per session instead of per type 
       // InnoDB: Gimme nested transactions! 
       if (!_transactions.ContainsKey(session)) 
       { 
        _transactions[session] = session.BeginTransaction(); 
       } 
      } 
     } 
    } 

    base.DoCommand(command); 
} 

編輯:關於該項目的更多的細節..

應用程序連接到使用NHibernate.Burrow幾個數據庫。每個線程都有它自己的會話

每個命令都有一個Do和Undo方法,並且我打算添加一個CanExecute方法來驗證網絡上的權限等prerequesites。每個命令在一個單一的工作上執行相當小的工作量子系統,一些連接到外部系統。

該類將嘗試運行列表中的每個命令,如果失敗,則回滾更改。 RepositoryCommand是一個適用於NHibernate的命令。列表中的命令可能鏈接到幾個不同的數據庫和外部系統,這些系統必須全部運行以保持數據處於一致狀態。

+0

爲什麼你需要這些嵌套事務?在我的應用程序中,我正在使用一個主要會話和輔助會話來處理並行運行的事情 - 到目前爲止,我對此沒有任何問題。如果你有很長時間的交易,你會打開一堆蠕蟲(至少這是給我們的) – bernhardrusch 2010-06-17 09:28:51

回答

0

事務應該是一個短暫的對象。 NHibernate不支持嵌套事務,所以這沒有幫助。

您應該重新考慮您處理交易的方式;我建議你閱讀關於工作單元模式。