java - 如何在 MDB 中停止回滚?

标签 java exception-handling transactions rollback message-driven-bean

我有一个 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 管理”事务模式,并使用 UserTransaction 从查找到 java:comp/UserTransaction 来调用 begin手动提交rollback,所以要注意异常处理。

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

    <
  • 否则,将您的 saveAuditData 方法移动到部署描述符中具有事务支持 RequiresNew 的 EJB StatelessBean,以便创建新事务并保存您的数据无论您的 MDB 交易发生什么。此选项可以与前一个选项结合使用。

关于java - 如何在 MDB 中停止回滚?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5437626/

相关文章:

postgresql - 我是否需要更高的事务隔离才能使约束在 PostgreSQL 中可靠地工作?

java - 通过脚本文件或通过 Java 代码初始化 SQL 数据库是否有任何继承优势?

java - 使用Java生成pdf : Making fields bold

c# - 最后阻止 try/catch 不起作用?

Java:如何编写 try-catch-repeat block ?

mysql - 如何在 MySQL 中的一个原子操作中重命名两个表

Java - 字符串索引超出范围

java - Java 中的构造函数调用

c# - UnhandledExceptionEventArgs 的全局异常处理程序不起作用

sql-server - 休眠/SQL Server : default lock mode