簡體   English   中英

JMS和Java EE事務

[英]JMS and Java EE transactions

如果您在EJB容器中運行了一些Java代碼(由JMS消息傳遞啟動),並且該代碼將另一個JMS消息放入同一隊列中,那么如何阻止該消息傳遞,直到將其踢掉的代碼完成為止和它的交易已提交? 基本上,我遇到交易並發問題。 我有JMS消息A所啟動的代碼(在EJB中)。該代碼完成了一些工作,然后進行了數據庫插入(由於容器管理的EJB事務,直到所有這些代碼執行完畢,它才提交)。 然后,它放入一條消息(消息B),該消息具有剛插入隊列中的數據庫行的ID。 然后,它會在同一事務中完成一些其他工作,而這需要花費一些時間。

好吧,將帶有數據庫行ID的消息放入隊列后不久,它就被傳遞並啟動了代碼,該代碼試圖查詢由消息A所啟動的代碼插入的行。麻煩是,那插入該行的代碼仍在執行,並且其事務尚未提交。 因此,有問題的數據庫行不在要查詢的數據庫中。 結果是由於消息B錯誤而啟動的代碼無法找到所需的數據庫行。

我該如何預防? 我已經完成了有關Java EE容器中的JMS和事務的數小時研究。 我讀過的一篇教程說,您無法在同一筆交易中收到消息並發送回復。 因此,在所有事務完成之前,容器是否不應該將消息提交到隊列中?

抱歉,這個問題很亂。 我正在盡力解釋。 這里粘貼的代碼太多了。 但是環境是WildFly 8.1,可執行代碼在無狀態EJB內,JPA用於數據庫訪問,消息在隊列中,而不是主題中。 我希望有足夠的信息。

// How factory and queues are declared in java code:

@Resource(mappedName = "java:/ConnectionFactory")
ConnectionFactory connectionFactory;

@Resource(mappedName = "java:jboss/exported/jms/queue/quequeA")
Queue queueA;

@Resource(mappedName = "java:jboss/exported/jms/queue/quequeB")
Queue queueB;

//Sending message:

TextMessage message = session.createTextMessage("some message goes here");
MessageProducer producer = session.createProducer(queueA); // samething for queueB
producer.send(message);

// how queues are configured in WidlFly's standalone.conf :

<jms-queue name="quequeA">
    <entry name="queue/quequeA"/>
    <entry name="java:jboss/exported/jms/queue/quequeA"/> <!-- same thing for queueB -->
</jms-queue>

<address-setting match="jms.queue.quequeA">
    <dead-letter-address>jms.queue.DLQ</dead-letter-address>
    <redelivery-delay>5000</redelivery-delay>
    <max-delivery-attempts>1</max-delivery-attempts>
    <max-size-bytes>10485760</max-size-bytes>
    <page-size-bytes>1048576</page-size-bytes>
    <address-full-policy>PAGE</address-full-policy>
    <message-counter-history-day-limit>10</message-counter-history-day-limit>
</address-setting>

// creating connection and session:
connection = connectionFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // note: the application is running in the Java EE web/EJB environment, so both "fasle" and auto_acknowledge arguments shoudl be ignored according to the javadoc. I'm trying to use container-managed transactions for everything

我不得不更改常規連接工廠:

@Resource(mappedName = "java:/ConnectionFactory")
ConnectionFactory connectionFactory;

到XA連接工廠:

@Resource(mappedName = "java:/JmsXA")
XAConnectionFactory connectionFactory;

這使事情一開始就停止了,因為我只在@PostConstruct中為每個EJB初始化一次連接,並在帶注釋的@PreDestroy方法中將其關閉。 因此,除此之外,我還必須將連接和會話生成移到每個方法的開頭,並在每個方法的末尾將其關閉。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM