3
我需要将JTA事务与发送JMS消息同步 - 应在客户端JTA事务提交后激活MDB。 这应该尽可能使用XAConnectionFactory,但在我的示例中不起作用。在提交JTA事务之前为JMS消息激活MDB
示例方案:
- Web服务客户端发送消息,代码= 0
- MDB接收消息并打印:START:代码(NEW JTA TRANSACTION)
- MDB增量代码和打印:SEND: %代码+ 1%
- MDB发送messag与新代码值
- MDB睡眠
- MDB打印:END代码
- 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客户端)
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); } } }
我做什么了?
这些都是很奇怪的症状。确实,MDB只允许NOT_SUPPORTED或REQUIRED事务注释,但我宁愿期望在部署时抛出异常,而不是默默地忽略REQUIRES_NEW。即便如此,+1有趣的后续行动。 – MaDa