2016-09-21 7 views
0

EJBコンテナ内で実行されている(JMSメッセージ配信によって開始された)Javaコードがあり、そのコードが別のJMSメッセージを同じキューに入れた場合、そのメッセージが配信されないようにするにはどうしますか?それを蹴ったコードは完了し、トランザクションはコミットされていますか?基本的には、トランザクションの並行性の問題が発生しています。私はJMSメッセージAによってキックオフされるコードを持っています。このコードはいくつかのことを行い、次にデータベース挿入を行います(コンテナ管理のEJBトランザクションのためにこのコードがすべて実行されるまでコミットしません)。次に、キューに挿入されたばかりのDB行のIDを持つメッセージ(メッセージB)を挿入します。それから、同じトランザクションで、少し時間がかかります。JMSおよびJava EEトランザクション

データベース行のIDをキューに入れた直後に、メッセージAによってキックオフされたコードによって挿入された行を照会しようとするコードが実行されます。問題は、その行を挿入したコードがまだ実行中で、そのトランザクションがまだコミットされていないことです。したがって、問題のデータベース行は照会されるDB内にありません。その結果、必要なDB行を見つけることができないため、メッセージBによってキックオフされるコードがエラーになります。

どうすればよいですか?私は、Java EEコンテナでJMSとトランザクションに関する数時間の研究を行ってきました。私が読んだこの1つのチュートリアルでは、同じトランザクションでメッセージを受信して​​返信することはできないということです。すべてのトランザクションが完了するまで、コンテナはメッセージをキューにコミットしないでください。

申し訳ありませんが、この質問が文字化けしています。私はできる限りのことを説明しようとしています。ここに貼り付けられるコードが多すぎます。しかし、環境はWildFly 8.1です。実行可能コードはステートレスEJBの内部にあり、JPAはデータベースアクセスに使用され、メッセージはトピックではなくキューにあります。私は十分な情報だと思います。私は、接続を一度だけ初期化されたため、

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

これは物事が最初に動作を停止製:

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

XA接続ファクトリへ:

// 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 
+0

メッセージのすべての話では、あなたは確かにJMSではなくJMXを意味しますか? – Nicholas

+0

申し訳ありませんが、JMS、あなたは正しいです。 – Creature

+0

を参照してください。http://stackoverflow.com/questions/13890287/jms-transaction – home

答えて

0

は、私は、通常の接続ファクトリを変更する必要がありました@PostConstruct内のEJBごとに作成し、@PreDestroy注釈付きメソッドでそれを閉じます。それに加えて、私は接続とセッションの生成を各メソッドの先頭に移動し、各メソッドの最後にそれらを閉じなければなりませんでした。

関連する問題