消息驱动的 bean - 事务支持
消息驱动的 bean 可以处理事务作用域中的目标(或端点)上的消息。
将消息侦听器服务与 IBM MQ JMS 配合使用时的事务处理
根据您选择的消息驱动 bean 部署描述符设置,有三种可能的情况: 容器管理的事务(必需)、容器管理的事务(不受支持)以及 bean 管理的事务。
在消息驱动的 bean 部署描述符设置中,您可以选择消息驱动的 bean 管理它自己的事务(bean 管理的事务)还是容器为该消息驱动的 bean 管理事务(容器管理的事务)。如果您选择容器管理的事务,在部署描述符笔记本中,您可以为 bean 的每种方法选择容器事务类型,以确定容器事务是必需的还是不受支持。缺省容器事务类型是必需的。
- 容器管理的事务(必需)
在这种情况下,应用程序服务器在读取任何来自目标的入局消息之前,并且在应用程序服务器调用消息驱动的 bean 的 onMessage() 方法之前会启动全局事务。这表示可以将消息轮流调用的其他 EJB 以及与资源(如数据库)的交互全部限定在此单个全局事务的作用域内。在此作用域内已获取入局消息。
如果此应用程序流成功完成,那么将落实该全局事务。如果此流未成功完成(因为事务被标记为进行回滚或出现运行时异常),那么将回滚事务,并且入局消息将回滚到消息驱动的 bean 目标中。
- 容器管理的事务(不受支持)
这种情况下,没有全局事务,但 JMS 提供程序仍可以将消息从消息驱动的 bean 目标传递到工作单元中的应用程序服务器中。因为此事务的事务作用域内未涉及其他资源,所以可以将其视为局部事务。
应用程序服务器将在成功完成消息驱动的 bean 的 onMessage() 分派时应答消息传递(使用消息驱动的 bean 的组装者指定的应答方式)。
但是,如果从 onMessage() 方法中抛出了未检查的运行时异常,那么应用程序服务器不会执行应答。这样,消息是否回滚到消息驱动的 bean 目标中呢(或者是否应答并删除消息呢)?
答案取决于 JMS 提供程序是否使用同步点,并且答案会随操作平台不同而变化(特别是,z/OS® 操作平台可以在此处产生不同的行为)。
在此容器管理的事务(不受支持)情况下,如果 JMS 提供程序在使用消息驱动的 bean 消息时建立同步点,那么在出现未检查的异常后,消息将回滚到目标中。
如果未使用同步点,那么在出现未检查的异常后,将从目标中删除消息。
要获取相关信息,请参阅 http://www.ibm.com/support/docview.wss?uid=swg21231549 上的技术说明“在同步点中获取非持久性消息时,MDB 在 z/OS 和分布式平台上的行为不同”。
- Bean 管理的事务
此这种情况下的行为类似于容器管理的事务(不受支持)情况。虽然这种情况下可能会有用户事务,但任何在消息驱动的 bean 的 onMessage 分派中启动的用户事务都不会将消息驱动的 bean 目标的消息使用包括在事务作用域中。为此,应使用容器管理的事务(必需)方案。
消息重新传递
在前面三种情况中的每种情况下,最终会重新分派回滚到消息驱动的 bean 目标中的消息。如果由于系统临时问题而导致原始回滚,那么您将期望重新分派消息驱动的 bean 并发出此消息以成功完成重新分派。但是,如果由于与特定消息相关的问题而导致回滚,那么将重复回滚并重新分派消息。这称为有害消息方案。
如果您的消息传递系统使用侦听器端口,那么应用程序服务器将通过以下方式来处理此情况:跟踪分派特定消息的频率,并在尝试重新传递此消息指定次数后停止关联侦听器端口。
- 最大重试次数
- 最大重试次数参数指定在侦听器停止前,侦听器尝试将特定消息传递到消息驱动的 bean 实例的次数。
- 如果此参数设置为 0,那么侦听器端口在成功传递单个消息故障后将停止。
如果您的消息传递系统使用激活规范,那么会以稍微不同的方式处理有害消息方案。虽然侦听器端口会跟踪特定消息已失败并重新传递的次数,激活规范还是会计算消息传递连续失败的次数。
- 在重复的消息失败时自动停止端点
- 您必须确保选择此选项。
- 此属性将在到达连续失败消息阈值时暂挂到端点的消息传递。
- 连续失败消息阈值
- 此参数确定有多少个消息传递被暂挂之前可以失败。
- 要启用此参数,必须选择在重复的消息失败时自动停止端点选项。
- 失败消息重试之间的延迟
- 此参数指定必须经过多少时间可重新传递之前未能成功传递的消息。
- 如果您为此参数指定 0,那么在重新传递消息之前没有延迟。
- 要启用此参数,必须选择在重复的消息失败时自动停止端点选项。
- 如果消息传递失败则停止端点
- 您必须确保选择此选项。
- 当到达在暂挂端点之前传递连续失败的次数时,此属性将暂挂到端点的消息传递。
- 在暂挂端点之前传递连续失败的次数
- 此参数确定有多少个消息传递被暂挂之前可以失败。
- 要启用此参数,您必须选择如果消息传递失败则停止端点选项。
在出现有害消息方案时,作为依赖应用程序服务器停止侦听器端口或激活规范的替代方法,您可以配置 IBM MQ 以解决问题。 对于队列目标,请对 IBM MQ 中的队列对象指定回退队列 (BOQUEUE) 和回退阈值 (BOTHRESH)。对于主题目标,请为 IBM MQ 系统队列 SYSTEM.DURABLE.MODEL.QUEUE 和 SYSTEM.NDURABLE.MODEL.QUEUE 指定回退队列 (BOQUEUE) 和回退阈值 (BOTHRESH)。如果执行此操作,那么 IBM MQ 将处理有害消息。 有关处理有害消息的更多信息,请参阅 IBM MQ 库的 IBM MQ“使用 Java™”一节。