3
JMSメッセージの送信とJTAトランザクションを同期する必要があります - クライアントJTAトランザクションコミット後にMDBをアクティブにする必要があります。 これはXAConnectionFactoryを使用すると可能ですが、私の例では機能しません。JTAトランザクションがコミットされる前のJMSメッセージのMDBアクティベーション
例のシナリオ:
- Webサービスクライアントはコードでメッセージを送る= 0
- MDBがメッセージ及びプリント受け取る:START:コード(NEW JTAトランザクション)
- MDB増分コードと印刷:SEND: %コード+
- MDBは新しいコード値でmessagを送って1%
- のmdb睡眠
- mdbファイルの印刷:ENDコード
- MDB仕上げ(トランザクションがCOMMIT)
シナリオは、私は結果を期待コード< 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