我正在使用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的命令。列表中的命令可能鏈接到幾個不同的數據庫和外部系統,這些系統必須全部運行以保持數據處於一致狀態。
爲什麼你需要這些嵌套事務?在我的應用程序中,我正在使用一個主要會話和輔助會話來處理並行運行的事情 - 到目前爲止,我對此沒有任何問題。如果你有很長時間的交易,你會打開一堆蠕蟲(至少這是給我們的) – bernhardrusch 2010-06-17 09:28:51