使用消息驱动 Bean (MDB) 生成新的 java 线程

发布于 2024-11-14 10:03:35 字数 233 浏览 4 评论 0原文

我可以从 MDB 中启动 /spawn 新的 java 线程吗? 我需要对 MDB 中的代码进行一些并行处理,然后将控制权返回给 MDB。

要求: 消息到达MDB,然后进行一些代码处理。然后启动两个新的从属线程来执行一些并行工作。直到那时 MDB 都在等待。当线程完成工作时。然后控制权返回给 MDB,MDB 完成相关的最终/清理工作。

从 MDB 启动一个新线程(可运行)是个好主意吗?如果不是那么应该有什么替代方案?

Can I start /spawn new java thread from within a MDB?
I have a requirement to do some parallel processing from code in MDB and then return the control back to MDB.

Requirement:
Message come to MDB , then some processing of code. Then two new slave thread are started which do some parallel work. Till then MDB is waiting. when threads finish the work. Then control is returned back to MDB, which completes the the related final/cleanup work.

Is it good idea to start a new thread ( Runnable) from MDB? If not then what should be the alternative?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

把梦留给海 2024-11-21 10:03:35

如果您在线程中执行事务性工作,那么这是一个坏主意。

当前正在由 EJB 容器启动的事务中执行工作的线程与事务上下文相关联。在您的情况下,MDB 中的 onMessage 方法启动一个新事务(除非您指定了 NotSupported 描述符),并且执行此事务的线程将与事务上下文关联。启动新线程不会将事务上下文传播到子线程。当容器检测到子线程正在尝试在没有事务上下文的情况下访问事务资源时,这将导致创建新事务。

尽管某些(或大多数?)事务管理器支持拥有相同事务上下文的多个线程的存在,但这可能(并且很可能)不适用于应用程序启动的线程。

It is a bad idea, if you are performing transactional work in the threads.

A thread that is currently performing work in a transaction started by the EJB container, is associated with a transaction context. In your case, the onMessage method in the MDB initiates a new transaction (unless you have specified a NotSupported descriptor), and the thread performing this transaction would be associated with a transaction context. Starting a new thread, does not propagate the transaction context to the child thread. This would result in a new transaction being created when the container detects that the child thread is attempting to access a transactional resource without a transaction context.

Although some (or most?) transaction managers support the presence of multiple threads possessing the same transaction context, this might (and most likely will) not apply to application initiated threads.

甜味拾荒者 2024-11-21 10:03:35

在 MDB 中启动新线程是不好的做法。它可以工作,但新线程不受应用程序容器的控制,因此可能会出现不可预测的行为。它们甚至可能会搞乱容器试图维护的线程管理。最糟糕的影响是,如果应用程序部署在集群中,那么用户定义的线程将严重失败。

在您的场景中:不要启动新线程,而是使用线程逻辑创建新的 MDB(这样它现在将由容器管理),然后将消息发送到这些新的 MDB。如果您希望将控制权返回给父 MDB,那么我认为,请在全局事务中使用父 MDB,以便父 MDB 将等待子 MDB 完成,然后控制权将返回。

Starting new threads with in MDB is bad practice. It will work but the new threads are not in control of application container so can behave unpredictably. They can even mess-up the thread management which container is trying to maintain. Worst affect is if the application is deployed in cluster then user defined threads will fail miserably.

In your scenario : Instead of starting new threads , create new MDB with logic of thread ( This way it will be managed by contaner now) then send message to these new MDB. If you want the control back to parent MDB then, I think , use your parent MDB in global transactional so that parent MDB will wait for child MDB to finish and control will return back.

巡山小妖精 2024-11-21 10:03:35

从 MDB 启动线程违反了规范。

Enterprise JavaBeansTM,版本 3.0,EJB 核心契约和要求第 21.1.2 节编程限制中规定:

  • 企业 Bean 不得使用线程同步原语来同步多个实例的执行。

  • 企业 Bean 不得尝试管理线程。企业 Bean 不得尝试
    启动、停止、挂起或恢复线程,或者更改线程的优先级或名称。企业 Bean 不得尝试管理线程组。

Starting a thread from an MDB violates the specification.

Enterprise JavaBeansTM,Version 3.0, EJB Core Contracts and Requirements states in section 21.1.2 Programming Restrictions:

  • An enterprise bean must not use thread synchronization primitives to synchronize execution of multiple instances.

  • The enterprise bean must not attempt to manage threads. The enterprise bean must not attempt
    to start, stop, suspend, or resume a thread, or to change a thread’s priority or name. The enterprise bean must not attempt to manage thread groups.

雨后彩虹 2024-11-21 10:03:35

您从根本上忽略了 Java EE 和 MDB 的要点。

Java EE 容器是一个托管运行时环境。 Java EE 容器背后的原则思想是,通过将某些正交关注点(例如事务管理)委托给容器,组件仍然专注于业务逻辑,并且(在乌托邦中)成为一个可重用的组件,对其运行时环境几乎不做任何假设。

在 MDB 之前,Java EE 容器是一个被动反应系统,无法协调容器端异步主动代理的操作。然后消息驱动 Bean 解决了这个问题,为您提供了在服务器端启动异步操作的标准方法。

您有一个由 MBD0 使用的原始事件 e0。对于消息,MDB0 将生成 e1 并将消息排队以响应 MBD1,然后该消息将完成其工作并将消息发送到 MDB2 等。

您可以使用 pub/sub 消息传递语义(以及具有异步语义的 o/c)实现由 n 个连续步骤组成的简单工作流程,并且所有涉及的线程都得到管理由容器。如果您希望让并发参与者工作,然后收集结果并启动最终操作,请考虑使用涉及 JMS 主题 的模式。

You are fundamentally missing the point of Java EE and MDBs.

A Java EE container is a managed runtime environment. The principle idea behind the Java EE container is that by delegating certain orthogonal concerns, such as transaction management, to the container, the component remains focused on business logic and (in utopia) be a reusable component that makes little assumption about its runtime environment.

Prior to MDBs, the Java EE container was a passive-reactive system that allowed no means for coordinating the action of a container side asynchronous active agents. Message Driven Beans then addressed this, providing a standard way for you to kick off an asynchronous action, server side.

You have an original event e0 which is consumed by MBD0. On message, MDB0 will generate e1 and queue a message in response to MBD1, which will then do its work and send msg to MDB2, etc.

There you have a simple workflow of n sequential steps using pub/sub messaging semantics (and o/c with asynchronous semantics), and all threads involved are managed by the container. If you wish to have concurrent actors working and then collecting results and kicking off a final action, consider using patterns involving JMS topics.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文