従来のシステムとJMSメッセージを統合し、JMSキューを利用する大規模なバッチジョブを配布するgrailsアプリケーションを構築しました。これらのメッセージングニーズをサポートするために、grails JMSプラグインを使用します。私たちは解決しようとしている不幸な一貫性の問題を発見しました。GrailsのJMSメッセージが古くなったデータを使ってサービスを処理するのはなぜですか?
典型的なプロセスフローは以下のとおりです。
- 外部システムは、当社のデータベースの状態を変更し、状態変化が当社のGrailsアプリケーションがデータベースから同じデータを引っ張って、メッセージを処理
- 発生したことをメッセージを送信します外部プロセスによって書かれたように(レガシーシステムによって変更されたクラス/テーブルでは、セカンダリキャッシュとクエリキャッシングは使用できません)。メッセージには多くのデータがありますが、grailsアプリケーションのクラスと識別子を使用します。
- これらのデータは、前のイベントを処理する際にJMS処理サービスがすでにデータとやり取りしていた場合には無効です。
ただし、同じデータを表示するコントローラにWebリクエストを行うと、データベースと一致します。
私たちの理論は、おそらく休止状態のセッションで、JMSイベントの処理の間にデータのキャッシングが存在するということです。 grailsのリクエスト処理は、一貫性を保証することを望んでいるように見えるので、私たちは同様のコードでイベント処理をラップする必要があると考えています。 hibernateセッションがJMSメッセージ間でデータを永続させている場合、私たちは各メッセージの休止セッションの設定と解除を検討していると推測しています。残念ながら、私たちは私たちのニーズに合ったコードを再利用できるように、これがどこで行われたのかを特定するためにgrails-coreをよく知っているわけではありません。
明らかに、外部システムとGrailsアプリケーションの両方が同じデータベースに書き込むことは理想的ではありません。私たちはレガシーシステムからの移行に伴ってこの問題に対処しています。そのため、すべてをgrailsアプリケーションに移行することが望まれますが、短期的な解決策としては実現不可能です。
メッセージ間にキャッシュされていたデータ構造体をロードする前に、次のコードを導入して問題を解決しました。sessionFactory.currentSession.flush() –