Jakarta ee 提交JTA事务之前JMS消息的MDB激活

Jakarta ee 提交JTA事务之前JMS消息的MDB激活,jakarta-ee,jms,jta,Jakarta Ee,Jms,Jta,我需要将JTA事务与发送JMS消息同步-MDB应该在客户端JTA事务提交后激活。 这在使用XAConnectionFactory时应该是可能的,但在我的示例中不起作用 示例场景: web服务客户端发送代码为0的消息 mdb接收消息并打印:开始:代码(新JTA事务) mdb增量代码和打印:发送:%code+1% mdb发送带有新代码值的消息 睡眠 mdb打印:结束代码 mdb完成(事务提交) 重复该场景,直到代码

我需要将JTA事务与发送JMS消息同步-MDB应该在客户端JTA事务提交后激活。 这在使用XAConnectionFactory时应该是可能的,但在我的示例中不起作用

示例场景:

  • web服务客户端发送代码为0的消息
  • mdb接收消息并打印:开始:代码(新JTA事务)
  • mdb增量代码和打印:发送:%code+1%
  • mdb发送带有新代码值的消息
  • 睡眠
  • mdb打印:结束代码
  • mdb完成(事务提交)
重复该场景,直到代码<10。我期望的结果是:

START: 0
SEND: 1
END: 0
START: 1
SEND: 2
END: 1
START: 2
SEND: 3
END: 2
etc..
但目前我得到:

...
START: 4
SEND: 5
END: 3
START: 5
SEND: 6
END: 4
START: 6
SEND: 7
END: 5
END: 6
我的代码:

  • Web服务客户端

    @WebMethod
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void publish() {
        TestQueueUtil.sendToQueue(0);
    }
    
  • TestQueueUtil(JMS客户端)

  • TestQueueMDB

    @MessageDriven(mappedName = "jms/dsk/TestQueue", activationConfig = {
            @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
            @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
    })
    public class TestQueueMDB implements MessageListener {
    
        @Resource
        protected MessageDrivenContext messageDrivenContext;
    
        @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
        public void onMessage(Message message) {
            Integer code = null;
            try {
    
                code = message.getIntProperty("code");
                System.out.println("START: " + code);
                if (code < 10) {
                    Integer newcode = code + 1;
                    System.out.println("SEND: " + newcode);
                    TestQueueUtil.sendToQueue(newcode);
                    Thread.sleep(2000);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                System.out.println("END: " + code);
            }
        }
    }
    
    @MessageDriven(mappedName=“jms/dsk/TestQueue”,activationConfig={
    @ActivationConfigProperty(propertyName=“acknowledgeMode”,propertyValue=“Auto acknowledge”),
    @ActivationConfigProperty(propertyName=“destinationType”,propertyValue=“javax.jms.Queue”)
    })
    公共类TestQueueMDB实现MessageListener{
    @资源
    受保护的MessageDrivenContext MessageDrivenContext;
    @TransactionAttribute(TransactionAttributeType.REQUIRES\u NEW)
    消息(消息消息)上的公共无效{
    整数代码=空;
    试一试{
    代码=message.getIntProperty(“代码”);
    System.out.println(“开始:+代码);
    如果(代码<10){
    整数newcode=code+1;
    System.out.println(“发送:+newcode”);
    TestQueueUtil.sendToQueue(新代码);
    《睡眠》(2000年);
    }
    }捕获(例外e){
    e、 printStackTrace();
    }最后{
    System.out.println(“结束:+代码);
    }
    }
    }
    

我做错了什么?

我发现我在MDB上没有事务上下文

当我通过调用

weblogic.transaction.TxHelper.getTransactionId() 
接收到null,当调用messageDrivenContext.getRollbackOnly()获取异常时

java.lang.IllegalStateException: [EJB:010156]Illegal attempt to call EJBContext.getRollbackOnly() from an EJB that was not participating in a transaction.
原因很简单

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
拆下或更换后

@TransactionAttribute(TransactionAttributeType.REQUIRED)
一切正常


:)

这些都是非常奇怪的症状。MDB确实只允许不支持或不需要的事务性注释,但我更希望在部署时引发异常,而不是默默地忽略REQUIRES\u NEW。即便如此,有趣的后续活动+1。
@TransactionAttribute(TransactionAttributeType.REQUIRED)