【问题标题】:Multiple Publish inside a transactionScope fails事务范围内的多次发布失败
【发布时间】:2012-11-05 10:10:53
【问题描述】:

我为不同子系统之间的集成架构建模。来自子系统的所有通知都使用原语Publish 发送到订阅的子系统。这些通知在Handler 方法内的for 循环中发送,因此它们都在同一个TransactionScope 中。我做了一个简单的例子来解释这一点:客户端向服务器发送一条消息,该服务器使用原语Publish 发送可变数量的消息。这是服务器处理程序:

public void Handle(MyMessage message)
    {

        for (int i = 0; i < message.numberOfNotifications; i++)
        {
            Bus.Publish<NotificationMessage>(m =>
            {
                m.myPersonalCount= i;
            }
            );
        }
    }

我正在寻找但我无法弄清楚的是,当我将 i 设置为 30 或更少时,一切正常。从 31 或更多我收到此错误消息:

could not execute query
[ SELECT this_.SubscriberEndpoint as y0_ FROM "Subscription" this_ WHERE this_.MessageType in (?) ]

查看内部异常我得到Unable to enlist in a distributed transaction

我使用原语 Send 尝试了相同的操作,但一切都是(尝试了 10k 条消息),所以这是一个仅与 Publish 指令相关的问题。

我将 Oracle 10g 用于 dbms,将 Oracle 11g 用于客户端。

如果端点不是事务性的,我没有任何问题,所以问题似乎只与 TransactionScope 有关。

感谢任何帮助,谢谢

【问题讨论】:

  • 你使用的是什么版本的 NServiceBus?
  • @ChrisBednarski 我使用版本 2.0.1329.2,我知道这是一个非常旧的版本..
  • 我建议迁移到新版本的 NSB - 类似于此处的回答 stackoverflow.com/a/12478656/136720
  • 您是否在注册表中打开了 Oracle MTS 跟踪?此外,还有另一个 MTS 资源池可能会限制您。
  • 是的,我打开了它,但看起来没问题,你说的另一个资源池是什么?如何监控它?

标签: oracle nservicebus transactionscope distributed-transactions


【解决方案1】:

无论如何,我都不是 Oracle 专家。我可能连新手的资格都达不到。

但是,我知道 NServiceBus 会为每个发布查询订阅存储,以防发布之间的订阅发生变化。

Oracle 客户端是否可能对分布式事务中可以登记的查询数量有某种限制?或许是为了防止 N+1 种性能问题?

也就是说,您想要发布 30 多个相同类型的活动似乎很奇怪。我想知道您的业务用例是什么。事件通常应该宣布发生了不可撤销的事情。为什么会发生 30 件事?

如果业务案例可靠,最好实现自己的订阅存储引擎,该引擎使用一些有限的缓存(甚至 5 秒),这样您就不会在每次发布时都返回查询数据库。

【讨论】:

  • 我有单个事件可以触发多达 20k 条通知消息。我这样做是因为我的系统预计具有很强的可扩展性,并且在我看来发送所有这些小消息而不是带有大量数据的消息更适合我的性能限制。你有什么想法?但是,如果端点不是事务性的,我没有任何问题,所以问题似乎在 TransactionScope 上下文中..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-17
  • 2018-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多