Menu Close

5.6.2.3. JTA トランザクション

Camel JMS ルートが JMS トランザクションに参加できるようにするには、追加の設定が必要です。camel-jms は spring-jms を中心に構築されているため、JBossEAP のトランザクションマネージャーおよび接続ファクトリーと連携できるようにいくつかの Spring クラスを設定する必要があります。以下のコード例は、CDI を使用してトランザクション JMS Camel ルートを設定する方法を示しています。

camel-jms コンポーネントには、org.springframework.transaction.PlatformTransactionManager タイプのトランザクションマネージャーが必要です。そのため、最初に JtaTransactionManager を拡張する Bean を作成します。Bean には @Named アノテーションが付けられており、Camel Bean レジストリー内に Bean を登録できることに注意してください。また、JBoss EAP トランザクションマネージャーとユーザートランザクションインスタンスは CDI を使用して注入されることに注意してください。

@Named("transactionManager")
public class CdiTransactionManager extends JtaTransactionManager {

  @Resource(mappedName = "java:/TransactionManager")
  private TransactionManager transactionManager;

  @Resource
  private UserTransaction userTransaction;

  @PostConstruct
  public void initTransactionManager() {
    setTransactionManager(transactionManager);
    setUserTransaction(userTransaction);
  }
}

次に、使用するトランザクションポリシーを宣言する必要があります。ここでも、@Named アノテーションを使用して Bean を Camel で利用可能にします。また、トランザクションマネージャーも、必要なトランザクションポリシーで TransactionTemplate を作成できるように注入されます。このインスタンスの PROPAGATION_REQUIRED

@Named("PROPAGATION_REQUIRED")
public class CdiRequiredPolicy extends SpringTransactionPolicy {
  @Inject
  public CdiRequiredPolicy(CdiTransactionManager cdiTransactionManager) {
    super(new TransactionTemplate(cdiTransactionManager,
      new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED)));
  }
}

これで、Camel RouteBuilder クラスを設定し、Camel JMS コンポーネントに必要な依存関係を注入できるようになります。JBoss EAP XA 接続ファクトリーは、以前に設定されたトランザクションマネージャーと注入されます。

この例では、queue1 からメッセージが消費されるたびに queue2 という名前の別の JMS キューにルーティングされます。queue2 から消費されるメッセージにより、JMS トランザクションは rollback () DSL メソッドを使用してロールバックされます。これにより、元のメッセージがデッドレターキュー (DLQ) に配置されます。

@Startup
@ApplicationScoped
@ContextName("jms-camel-context")
public class JMSRouteBuilder extends RouteBuilder {

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

  @Inject
  CdiTransactionManager transactionManager;

  @Override
  public void configure() throws Exception {
    // Creates a JMS component which supports transactions
    JmsComponent jmsComponent = JmsComponent.jmsComponentTransacted(connectionFactory, transactionManager);
    getContext().addComponent("jms", jmsComponent);

    from("jms:queue:queue1")
      .transacted("PROPAGATION_REQUIRED")
      .to("jms:queue:queue2");

    // Force the transaction to roll back. The message will end up on the Wildfly 'DLQ' message queue
    from("jms:queue:queue2")
      .to("log:end")
      .rollback();
  }