9.2. トランザクションエンドポイントによる境界
ルート開始時のコンシューマーエンドポイントがリソースにアクセスすると、エクスチェンジのポーリング後にトランザクションを開始するため、transacted()
コマンドを使用する意味がありません。つまり、トランザクションの開始が遅すぎて、コンシューマーエンドポイントをトランザクションスコープに含めることができません。この場合、正しい方法は、トランザクションを開始するエンドポイント自体を設定することです。トランザクションを管理できるエンドポイントは、トランザクションエンドポイント と呼ばれます。
トランザクションエンドポイントによる境界設定には、次の 2 つの異なるモデルがあります。
一般的なケース: 通常、トランザクションエンドポイントは以下のようにトランザクションを区切ります。
- 交換がエンドポイントに到着したとき、またはエンドポイントが交換のポーリングに成功したとき、エンドポイントは関連するトランザクションマネージャーを呼び出してトランザクションを開始します。
- エンドポイントは新しいトランザクションを現在のスレッドに割り当てます。
- エクスチェンジがルートの最後に到達すると、トランザクションエンドポイントはトランザクションマネージャーを呼び出して現在のトランザクションをコミットします。
- InOut エクスチェンジのある JMS エンドポイント: JMS コンシューマーエンドポイントが InOut エクスチェンジを受信し、このエクスチェンジが別の JMS エンドポイントにルーティングされる場合は、特別なケースとして扱う必要があります。問題は、要求/応答交換全体を 1 つのトランザクションで囲み込もうとすると、ルートがデッドロックになってしまう可能性があることです。
9.2.1. JMS エンドポイントを使用したルートの例
「トランザクションエンドポイントによる境界」 は、ルート (from()
コマンド内で) の開始時にトランザクションエンドポイントがあることによってルートがトランザクションになる例を示しています。すべてのルートノードがトランザクションスコープに含まれます。この例では、ルートのすべてのエンドポイントが JMS リソースにアクセスします。
9.2.2. Java DSL でのルート定義
以下の Java DSL の例は、トランザクションエンドポイントでルートを起動してトランザクションルートを定義する方法を示しています。
from("jmstx:queue:giro") .to("jmstx:queue:credits") .to("jmstx:queue:debits");
上記の例では、トランザクションスコープにエンドポイント jmstx:queue:giro
、jmstx:queue:credits
および jmstx:queue:debits
が含まれます。トランザクションに成功すると、エクスチェンジは giro
キューから永続的に削除され、credits
キューおよび debits
キューにプッシュされます。トランザクションが失敗すると、エクスチェンジは credits
および debits
キューに配置されず、エクスチェンジは giro
キューに戻されます。デフォルトでは、JMS はメッセージの再配信を自動的に試行します。以下のように、JMS コンポーネント Bean jmstx
はトランザクションを使用するように明示的に設定する必要があります。
<blueprint ...> <bean id="jmstx" class="org.apache.camel.component.jms.JmsComponent"> <property name="configuration" ref="jmsConfig" /> </bean> <bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration"> <property name="connectionFactory" ref="jmsConnectionFactory" /> <property name="transactionManager" ref="jmsTransactionManager" /> <property name="transacted" value="true" /> </bean> ... </blueprint>
前述の例では、トランザクションマネージャーインスタンス jmsTransactionManager
は JMS コンポーネントに関連付けられ、transacted
プロパティーは true
に設定され、InOnly エクスチェンジのトランザクションデマケーションを有効にします。
9.2.3. Blueprint XML でのルート定義
上記のルートは、以下のように Blueprint XML で表現できます。
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> <camelContext xmlns="http://camel.apache.org/schema/blueprint"> <route> <from uri="jmstx:queue:giro" /> <to uri="jmstx:queue:credits" /> <to uri="jmstx:queue:debits" /> </route> </camelContext> </blueprint>
9.2.4. DSL transacted()
コマンドは必要ありません。
トランザクションエンドポイントで始まるルートに transacted()
DSL コマンドは必要ありません。ただし、デフォルトのトランザクションポリシーが PROPAGATION_REQUIRED
(「トランザクション伝播ポリシー」 を参照) であることを仮定すると、以下の例のように transacted()
コマンドを含めることは通常問題ありません。
from("jmstx:queue:giro") .transacted() .to("jmstx:queue:credits") .to("jmstx:queue:debits");
ただし、このルートは、デフォルト以外の伝播ポリシーを持つ単一の TransactedPolicy
Bean が Blueprint XML で作成されている場合など、このルートが予期せぬ方法で動作する可能性があります。「デフォルトのトランザクションマネージャーおよびトランザクションポリシー」を参照してください。そのため、通常はトランザクションエンドポイントで始まるルートに transacted()
DSL コマンドを含めない方がよいでしょう。
9.2.5. ルート開始時のトランザクションエンドポイント
以下の Apache Camel コンポーネントは、ルートの開始点で表示される場合にトランザクションエンドポイントとして機能します。たとえば、from()
DSL コマンドに表示される場合です。つまり、これらのエンドポイントはトランザクションクライアントとして動作するよう設定でき、トランザクションリソースにもアクセスできます。
- ActiveMQ
- AMQP
- JavaSpace
- JMS
- JPA