2010-06-17 166 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不支持嵌套事务,所以这没有帮助。

您应该重新考虑您处理交易的方式;我建议你阅读关于工作单元模式。