WebSphere 7中的消息驱动Bean(EJB3),XA事务,错误处理

时间:2011-11-28 17:44:30

标签: java ejb jms websphere message-driven-bean

我是EJB的新手。背景:我有一个使用WebSphere缺省消息传递提供程序的MDB接收具有java.sql.DataSource的MapMessages来做一些工作,使用preparedstatement,jdbc事务等。我在ibm-ejb-bnd.xml中设置了MDB, ejb-jar.xml使用带有激活规范和目标名称的JCA适配器。我在ejb-jar和ibm-ejb-jar-bind中添加了一个java.sql.DataSource。我还在MessageListener中添加了带有@Resource注释的DataSource。

2个场景我无法理解(第一个场景已修复,请参阅更新)......

容器管理的MDB: DataSource驱动程序不兼容XA,因此我在WebSphere中启用了“Last Participant Support”。但是,当MDB事务类型设置为Container时,我在提交时收到错误:

[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消息,MDB是异步,AUTO-ACKNOWLEDGE。收到消息后,可以确认消息。

如果我引入了一个应用程序错误,所以有一个Exception,我立即看到这个错误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次,立即抛出与Container Managed MDB相同的错误:“EJB抛出了一个意外的(未声明的)异常......”

如果我抛出RuntimeException,则不会发生“未声明(未声明)的消息”消息,但消息仍然会立即重试4次,而不是等待重试延迟。

感谢阅读,非常感谢任何帮助或见解!

更新:我最终通过将数据源切换为兼容XA来解决XA兼容性问题。在WAS管理控制台中:Resources-> JDBC Providers-> DB2 Universal JDBC Driver Provider->将实现类名更改为:com.ibm.db2.jcc.DB2XADataSource

但是当消息失败时,我仍然遇到同样的问题。它会立即重试,而不是根据WAS中的ActivationSpec。

2 个答案:

答案 0 :(得分:4)

我认为激活规范中的重试间隔是关于已关闭的连接,而不是失败的消息。

您应该在SIB目的地中定义所需的时间间隔

公共汽车>总线>目的地> DESTINATION

查看例外目的地

每条消息的最大失败递送次数是消息在声明失败之前发送的次数(默认值为5,这就是为什么再次获得4次)

当消息失败时,它将移动到异常目标队列,或者如果设置为None,将在一定时间后重试,该时间在总线级别设置但可以为每个目标覆盖(请参阅覆盖消息传递引擎阻止)重试超时默认值)

答案 1 :(得分:0)

我不知道你是否仍然需要它,但你应该检查自定义属性: 为消息传递引擎定义sib.processor.blockedRetryTimeout

这是您要搜索的内容,在邮件等待重新传递的过程中,它处于UNLOCKED状态,因此可以被丢弃。