gpt4 book ai didi

jakarta-ee - 在提交 JTA 事务之前为 JMS 消息激活 MDB

转载 作者:行者123 更新时间:2023-12-01 12:58:13 34 4
gpt4 key购买 nike

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

示例场景:

  • Web 服务客户端发送代码为 0 的消息
  • mdb 接收消息并打印:START: code (NEW JTA TRANSACTION)
  • mdb 递增代码并打印:SEND: %code + 1%
  • mdb 发送带有新代码值的消息
  • mdb sleep
  • 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

我的代码:

  • 网络服务客户端

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

    public static void sendToQueue(Integer code) {
    InitialContext initialContext;
    XAQueueConnection queueConnection = null;
    XAQueueSession queueSession = null;

    try {
    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
    initialContext = new InitialContext(env);
    XAConnectionFactory queueConnectionFactory = (XAConnectionFactory) initialContext.lookup("jms/dsk/ConnectionFactoryXA");

    queueConnection = (XAQueueConnection) queueConnectionFactory.createXAConnection();
    queueConnection.start();

    queueSession = queueConnection.createXAQueueSession();
    Queue queue = (Queue) initialContext.lookup("jms/dsk/TestQueue");

    //QueueSender sender =
    MessageProducer producer = queueSession.createProducer(queue);
    Message jmsMessage = queueSession.createMessage();

    jmsMessage.setIntProperty("code", code);
    producer.send(jmsMessage);
    producer.close();
    queueConnection.stop();

    } catch (Exception e) {
    throw new RuntimeException("sendToQueue", e);
    } finally {
    if (queueSession != null) {
    try {
    queueSession.close();
    } catch (Exception e) {
    //ignore
    }
    }
    if (queueConnection != null) {
    try {
    queueConnection.close();
    } catch (Exception e) {
    //ignore
    }
    }
    }

    }
  • 测试队列MDB

    @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);
    }
    }
    }

我做错了什么?

最佳答案

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

当我通过调用检查交易ID时

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)

一切正常。

:)

关于jakarta-ee - 在提交 JTA 事务之前为 JMS 消息激活 MDB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8415959/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com