繁体   English   中英

如何在MDB中停止回滚?

[英]How to stop rollback in MDB?

我有一个onMessage方法,我从队列中恢复一个ObjectMessage并使用该信息来填充和持久化JPA实体对象。 但是当持久化实体对象出现问题时,它会重新执行onMessage()。 我的猜测是它将ObjectMessage推回队列,因此onmessage再次被执行。 这样我就进入了无限循环。 如何停止onMessage()再次执行或控制执行的次数。 这是我的代码。 saveAuditData(auditInfo)发生错误。

public void onMessage(Message inMessage) {
   log.debug("Entering onMessage() Method.");
   AuditInfo auditInfo = null;
   try {
       ObjectMessage om = (ObjectMessage) inMessage;  
       auditInfo = (AuditInfo) om.getObject();
       log.debug("Message received : " + auditInfo.getApiUsed());
       log.debug("Calling saveAuditData().");
       saveAuditData(auditInfo);
       log.debug("Leaving onMessage() Method.");
   }
   catch (Exception e) {
       e.printStackTrace();
       log.debug("Error persisting Audit Info.",e);
       log.debug("Printing Audit Info:");
       log.debug(auditInfo.toString());
   }

}
private void saveAuditData(AuditInfo auditInfo) {
    log.debug("Entering saveAuditData() Method.");
    log.debug("Populating Audit Object.");
    IdmAudit idmAudit = new IdmAudit();
    idmAudit.setApiUsed("API");
    idmAudit.setAppClientIpAddress("localhost");
    idmAudit.setAuditActivity("activity1");
    idmAudit.setAuditData(auditInfo.getAuditData());
    idmAudit.setAuditGroup(AUDIT_GROUP);
    idmAudit.setAuditType("Type");
    idmAudit.setIdmAuditCreationDate(new Date());
    idmAudit.setLocationCd("Location");
    idmAudit.setPurgeDate(null);
    idmAudit.setSubscriberId(new BigDecimal(0));
    idmAudit.setSuccessInd("Y");
    idmAudit.setUserId(new BigDecimal(0));
    idmAudit.setAuditSource("Source");
    idmAudit.setVersionNumber(new BigDecimal(0));

    log.debug("Saving Audit.");
    entityManager.persist(idmAudit);
    entityManager.flush();
    log.debug("Leaving saveAuditData() Method.");
}

当容器启动容器管理的事务以处理JMS消息时,JDBC连接中的任何故障或线程中引发的异常都将导致全局XA事务的回滚。 因此,消息将返回到队列,稍后将根据队列配置重试:重试之间的时间段,在将消息移动到死信队列之前的最大重试次数。

所以你有以下选择:

  • 在MDB部署描述符中选择“Bean managed”事务模式,并使用UserTransaction从lookup到java:comp/UserTransaction手动调用begincommitrollback ,所以要小心处理异常。

  • 保持“容器管理”事务,但查询JMS消息上的重新传递计数属性以决定下一步操作:再次尝试可能失败的操作或跳过此步骤并将数据保存在数据库中。 如果您的JMS提供程序提供消息,您可以从Message.getJMSRedelivered()Message.getLongProperty("JMSXDeliveryCount")获取有关消息的重新传递信息。

  • 或者,将saveAuditData方法移动到EJB StatelessBean,并在部署描述符中使用事务支持RequiresNew ,以便创建新事务并保存数据,无论MDB事务发生什么。 此选项可与前一个选项组合使用。

您只需使用TransactionType注释标记onMessage方法:

@TransactionAttribute(value=TransactionAttributeType.REQUIRES_NEW)
public void onMessage(Message message) {
     .....
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM