【问题标题】:Running multiple nhibernate sessions in a transaction在事务中运行多个休眠会话
【发布时间】:2012-02-23 11:59:35
【问题描述】:

我正在开发一个 WPF 应用程序,该应用程序需要在特定操作期间执行大量更新和插入操作。我们正在使用 Fluent Nhibernate 3.2。 我想在一个事务中执行所有更新和插入,这样如果有任何错误我可以回滚所有步骤。 我们为每个步骤定义了命令。 问题在于,在其中一个插入命令中,我们使用了 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();
            }
        }
    }

事务范围似乎不起作用,因为我收到一个错误 “该操作对事务的状态无效”。

这是事务范围的正确用法吗? 关于我如何进步的任何建议?

谢谢。

【问题讨论】:

  • 为什么不对所有命令使用同一个会话?
  • 我可以..如果我没有在其中一个命令中使用 Parallel.Foreach。
  • 据我所知,您是正确的,因为 NHibernate 要求每个会话在单独的线程中运行。这里的例子有帮助吗? stackoverflow.com/questions/1192111/…
  • 它应该遵守事务范围,但这取决于数据提供者。如果您使用的是 SQL Server,它应该可以正常工作,但这里没有指定。还要了解,跨多个连接它会尝试使用您可能不想要的分布式事务协调器。
  • 每当我看到有人说“我们实施了工作单元”时,它都会为我竖起一个黄旗。 [根据 Martin Fowler 的说法] (martinfowler.com/eaaCatalog/unitOfWork.html),“工作单元会跟踪您在业务交易期间所做的所有可能影响数据库的事情。完成后,它会计算出需要做的所有事情来改变数据库作为你工作的结果。”这正是 NHibernate 会话为您所做的。它已经实现了 UoW。

标签: nhibernate session transactions


【解决方案1】:

不要这样做。如果要考虑性能问题,NHibernate 为 MSSqlServer、Oracle 和 Postgres 提供了批处理策略,它们会在合理数量的批处理/db 调用中处理更新/插入。不要在多个线程上共享会话(你不这样做),最好不要只使用 DTS 来使用 Parallel.ForEach。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-14
    • 2012-11-11
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    • 2014-07-26
    • 2011-06-08
    相关资源
    最近更新 更多