【发布时间】:2012-01-08 03:47:34
【问题描述】:
我是 EJB 的新手。背景:我有一个使用 WebSphere 默认消息传递提供程序接收 MapMessages 的 MDB,它有一个 java.sql.DataSource 来做一些工作,使用preparedstatement、jdbc 事务等。我在 ibm-ejb-bnd.xml 和ejb-jar.xml 使用具有激活规范和目标名称的 JCA 适配器。我在 ejb-jar 和 ibm-ejb-jar-bind 中添加了一个 java.sql.DataSource。我还在 MessageListener 中添加了带有 @Resource 注释的 DataSource。
2 个场景我无法理解(第一个场景已修复,请参阅更新)...
容器管理的 MDB: DataSource 驱动程序与 XA 不兼容,因此我在 WebSphere 中启用了“最后参与者支持”。不过,当 MDB 事务类型设置为容器时,我在提交时收到错误:
[11/28/11 10:56:10:988 MST] 0000002e RegisteredRes E WTRN0063E: An illegal attempt to commit a one phase capable resource with existing two phase capable resources has occurred.
也许这是因为在 DataSource 提交后,返回到 MessageListener 提交使其成为最后一个参与者?我相信 WAS 7 中的默认消息传递提供程序与 XA 兼容,尽管我还没有看到任何明确说明的文档。
消息在第一个错误后立即重新运行 4 次(即使根据 WebSphere 中的 ActivationSpec 应该有 30 秒的延迟)。每次抛出相同的错误。根据 MessageListener 它没有错误地完成,所以这个错误是美妙的隐形容器管理事务的一部分。我认为我不需要 XA 全局事务,因为除了 JMS 之外只有一个 DataSource,我以编程方式处理事务回滚。 JMS msg,MDB 也是异步的,AUTO-ACKNOWLEDGE。一旦收到消息,就可以确认。
如果我引入了应用程序错误,因此出现异常,我会立即看到此错误 5 次(无延迟):
[11/28/11 10:16:18:857 MST] 0000002b LocalExceptio E CNTR0020E: EJB threw an unexpected (non-declared) exception during invocation of method "onMessage" on bean...
所以我切换到......
Bean 托管 MDB: 提交在没有 XA 错误的情况下工作,并且只发生一次。然而,错误处理仍然没有像我期望或想要的那样表现!在 MessageListener 类中,捕获的异常抛出了一个 EJB 异常,我认为这应该导致 MDB 具有我想要的行为:异常的原因对我来说并不重要,当 MDB 抛出一个捕获的异常时,不应该是否根据 WebSphereActivationSpec 中的属性重试 MDB? 而是消息转到 MessageListener 5 次,立即引发与容器管理 MDB 相同的错误:“EJB 引发了意外(未声明的)异常......”
如果我抛出 RuntimeException,则不会发生“未加速(未声明)预期”消息,但该消息仍会立即重试 4 次,而不是等待重试延迟。
感谢阅读,非常感谢任何帮助或见解!
更新:我最终通过将数据源切换为 XA 兼容解决了 XA 兼容性问题。在 WAS 管理控制台中:Resources->JDBC Providers->DB2 Universal JDBC Driver Provider->将实现类名更改为:com.ibm.db2.jcc.DB2XADataSource
当消息失败时,我仍然遇到同样的问题。它会立即重试,而不是根据 WAS 中的 ActivationSpec。
【问题讨论】:
标签: java ejb jms websphere message-driven-bean