JTA がシングルスレッドであることと同じ理由です。スレッドがいつどのように実行されるかについて、確実な保証はありません。さらに、同期がないと、スレッドがいつ作業を完了するかについての保証はありません。これらの制約があるため、並列処理の利点を維持しながらトランザクションの保証を作成することは困難です。
たとえば、トランザクションを生成し、そのトランザクションでメッセージを送信するスレッドを生成するが、メイン スレッドで任意にトランザクションをコミットする場合、トランザクション マネージャーは何をすべきか (? を無視し、commit()
? を失敗させsend()
ます)。完了していない他のトランザクション作業 (データベース コミット) があるが、メッセージ送信スレッドが完了して呼び出された場合はどうなりcommit()
ますか? 2-Phase-Commit
TransactionManager がすべてのトランザクション参加者のステータスを判断しようとしているときに、スレッドがスピンアップしてさらに作業を開始するとどうなるでしょうか?
トランザクション API はすべて、明確に定義された作業単位に基づいています。作業単位が単一のスレッドで実行される場合、これらの API は非常に明確です。そうしないと事態は複雑になり、Java EE 仕様で扱われていない実装によってカバーされます。これらのトランザクション マネージャーでは、ネストされたトランザクションや、複数のスレッドにまたがるトランザクションが可能です。これらの実装は、非常に慎重に設計された同期を使用し、使用例が限られているため、とにかく作業をシリアル化するだけになる可能性があります。
ほとんどのユーザーにとって、JMS の主な利点は、メッセージ ベースのアクター システムの場合と同様です。多くの個別のステップは、キューのメッセージをプルして処理し、結果を別のキューに置くことで次のステップに進むことができます。いずれかのステップがボトルネックになった場合は、処理エージェント (MDB、Spring Bean など) を追加するだけです。各エージェントは単一のスレッドで処理を行い、さらにエージェントを作成することで複数のコアにスケーリングします。