在事务中运行多个nhibernate会话

在事务中运行多个nhibernate会话,nhibernate,session,transactions,Nhibernate,Session,Transactions,我正在开发一个WPF应用程序,它需要在特定操作期间执行大量更新和插入。我们使用的是Fluent Nhibernate 3.2。 我希望在一个事务中执行所有更新和插入,以便在出现任何错误时回滚所有步骤。 我们已经为每个步骤定义了命令。 问题在于,在其中一个insert命令中,我们使用了Parallel.Foreach循环,在该循环中,我们为每个线程创建了一个新的无状态会话 现在,如果我想将所有这些命令包装到一个事务中,我该怎么做 我们已经实现了UnitOfWork,但它不允许一次执行多个会话。因此

我正在开发一个WPF应用程序,它需要在特定操作期间执行大量更新和插入。我们使用的是Fluent Nhibernate 3.2。 我希望在一个事务中执行所有更新和插入,以便在出现任何错误时回滚所有步骤。 我们已经为每个步骤定义了命令。 问题在于,在其中一个insert命令中,我们使用了Parallel.Foreach循环,在该循环中,我们为每个线程创建了一个新的无状态会话

现在,如果我想将所有这些命令包装到一个事务中,我该怎么做

我们已经实现了UnitOfWork,但它不允许一次执行多个会话。因此,我考虑离开UnitOfWork,直接将Sessionfactory传递给每个命令。然后,每个命令都创建自己的会话并执行它。 我们有一个执行所有命令的命令处理器:

public class CommandProcessor : ICommandProcessor
    {
        public void ExecuteCommands ( IEnumerable<ICommand> commands)
        {
            using (var scope = new TransactionScope(TransactionScopeOption.Required))
            {
                foreach (var command in commands)
                {
                        command.Execute(UnitOfWork.UnitOfWorkFactory.SessionFactory);
                }

                scope.Complete();
            }
        }
    }
公共类CommandProcessor:ICommandProcessor
{
public void ExecuteCommands(IEnumerable命令)
{
使用(var范围=新TransactionScope(TransactionScopeOption.Required))
{
foreach(命令中的var命令)
{
command.Execute(UnitOfWork.UnitOfWorkFactory.SessionFactory);
}
scope.Complete();
}
}
}
当我遇到错误时,事务作用域似乎不起作用 “该操作对于事务的状态无效”

这是事务范围的正确用法吗? 对我的进步有什么建议吗


谢谢。

不要这样做。如果您想考虑性能问题,NHiBiNT为MSQLSLover、Oracle和PoSGRESs提供批处理策略,这些策略将处理合理数量的批处理/数据库调用中的更新/插入。不要在多个线程上共享会话(您不这样做),最好不要仅在使用Parallel.ForEach时使用DTS

为什么不对所有命令使用相同的会话?如果我没有在其中一个命令中使用Parallel.Foreach,我可以..如果我没有在其中一个命令中使用Parallel.Foreach。从我所了解到的情况来看,您是正确的,NHibernate要求每个会话在单独的线程中运行。这里的例子有帮助吗?它应该尊重事务范围,但它取决于数据提供者。如果您使用的是SQL Server,它应该可以正常工作,但这里没有指定。还要了解,在多个连接中,它将尝试使用分布式事务协调器,这可能是您不想要的。每当我看到有人说“我们实现了工作单元”,它就会给我升起一个黄旗。[根据Martin Fowler的说法](),“一个工作单元跟踪您在业务事务中所做的可能影响数据库的一切。当您完成时,它会计算出由于您的工作而需要更改数据库的一切。”这正是NHibernate会话为您所做的。它已经实现了UoW。