我正在使用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