我需要将JTA事务与send JMS消息同步 - 在客户端JTA事务提交后应该激活MDB。 这应该在使用XAConnectionFactory时可能,但在我的示例中不起作用。
示例场景:
场景重复直到代码< 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
我的代码:
Webservice客户端
@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
}
}
}
}
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);
}
}
}
我做错了什么?
答案 0 :(得分:4)
我发现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)
一切正常。
:)