Translated message

A translation of this page exists in English.

Warning message

This translation is outdated. For the most up-to-date information, please refer to the English version.

JBossTS の XA トランザクションリカバリ機能を有効化するには、どのように JBoss を設定すればよいでしょうか?

Solution Verified - Updated -

Environment

  • JBoss Enterprise Application Platform (EAP)
    • 4.x
    • 5.x
  • JBoss Enterprise SOA Platform (SOA-P)
    • 4.x
    • 5.x
  • JBoss Enterprise Portal Platform (EPP)
    • 4.x
    • 5.x

Issue

JBossTS の XA トランザクションリカバリ機能を有効化するには、どのように JBoss を設定すればよいでしょうか?

Resolution

はじめに

JBoss Enterprise Application Platform (EAP) 4.2 以降のリリースには、耐障害性を持つトランザクションマネージャである JBossTS が含まれています。<xa-datasource> で定義する JDBC 接続や、2 フェーズトランザクションの JBoss Messaging を使用した JMS 接続のなどの XAResources を参加させると、JBossTS は、トランザクション時にアプリケーションサーバーのクラッシュ時にリカバリするためのトランザクションログを (JBOSS_HOME/server/$PROFILE/data/tx-object-store に) 保存します。適切なリカバリモジュールが設定されると、すべてのリソースが再度利用できるようになったときに、もっとも失敗したトランザクションが自動的にリカバリされます。

この中で述べている設定は、サーバー設定配下の conf ディレクトリにある jbossjta-properties.xml もしくは jbossjts-properties.xml に設定します(デフォルトで設定されているものもあります。)

EAP 4.x が $JBOSS_HOME にインストールされているときに、default サーバー設定プロフィルを使用している場合の設定ファイルのパスは以下のようになります。

$JBOSS_HOME/server/default/conf/jbossjta-properties.xml

EAP 5.x が $JBOSS_HOME にインストールされているときに、default サーバー設定プロフィルを使用している場合の設定ファイルパスは以下のようになります。

$JBOSS_HOME/server/default/conf/jbossts-properties.xml

クラスタ構成時に関する注意事項

まず、それぞれのアプリケーションサーバーのインスタンスは、自身がトランザクションのコーディネーター(つまりトランザクションマネージャ)として調停しているトランザクションリカバリに対して責任を負います。通常、データベースなどリソースマネージャーは複数のアプリケーションサーバーからアクセスされますので、複数のコーディネーターのトランザクションに参加することになります。トランザクションリカバリ時に、トランザクションマネージャである JBossTS は、各リソースマネージャに対して潜在的にリカバリ可能な in-doubt トランザクションのリストを要求します。データベースなどリソースマネージャは すべての in-doubt トランザクションを返すことでこれに答えますが、これには自身がコーディネートしていないものも含まれます。自身がコーディネートしているトランザクションを効果的に選別するために、共通のデータベースを共有する各アプリケーションサーバーでは、各インスタンスごとに固有のノードIDを設定する必要があります。これを行うために以下のプロパティに固有の値を設定してください。

<property name="com.arjuna.ats.arjuna.xa.nodeIdentifier" value="1"/>

あわせて、リカバリマネージャーがどのノードIDをリカバリすべきかを指定する設定も必要となります。もちろん、これは上で設定した nodeIdentifier に一致している必要があります。

<property name="com.arjuna.ats.jta.xaRecoveryNode" value="1"/>

リカバリモジュール

通常、リカバリが望まれるそれぞれの XA リソースは、jbossjta-properties.xml/jbossts-properties.xml の "jta" セクションにリカバリモジュールを設定する必要があります。リカバリモジュールは、com.arjuna.ats.jta.recovery.XAResourceRecovery を拡張したものである必要があり、JBoss ではデフォルトで JDBC および JMS の XA リソースに対するリカバリモジュールを提供しています。

JDBC リカバリ

JBoss EAP 5.1 以降からでは、JDBC XA リソースのリカバリ設定を非常に簡単にするための変更が入りました。簡単に言えば、リカバリ設定は自動的に行われるようになりましたので、明示的な設定は基本的には必要なくなりました。ただし、これは <xa-datasource> の接続ユーザーに指定されている認証情報が、リカバリを実行するために RDBMS で必要なアクセス権を持っていることを前提としています。そこで、接続ユーザーとは別にリカバリ用の認証情報を設定することも可能なように、データソース設定 (つまり *-ds.xml ファイル)に以下の4つの新しい属性が追加されました。

  • recover-user-name
  • recover-password
  • recover-security-domain
  • no-recover

最初の2つは、リカバリ作業を実行するための認証情報を持つ、ユーザーとパスワードのペアとなります。3つ目も、最初の2つと用途は同じくリカバリで仕様される認証情報を設定するものですがセキュリティドメインを使用しています(これはこちらにあるような方法でパスワードを暗号化する際に有用なものです)。最後の4つめフィールドは、該当データソースをリカバリから除外するための設定です。
リカバリ用の認証情報が最初の3つの設定値によって設定されていない場合には、通常の接続ユーザーの認証情報 (つまり、User、Password、および security-domain) が利用されるようにフォールバックされます。このように通常の接続ユーザーとは別にリカバリ専用の認証情報を設定可能なようになったのは、なぜなら多くのデータベースベンダーが、アプリケーションで使用される「通常の」接続ユーザーの認証情報に付与するには適さないような、特別なアクセス権をリカバリを実行する際に求めることがあるためです。

JBoss EAP 5.1 以前のリリースでは、自動では設定されないので、JDBC データソースに対して手動でのリカバリモジュールの設定が必要になります。リカバリ対象のデータソースごとに以下のようなリカバリマネージャをすることで、それぞれのリソースをリカバリできるようになります。1つのインスタンスが複数のデータソースにリカバリマネージャを設定する場合、各リカバリマネージャの "name" はユニークにする必要があり、データソース <jndi-name> 名を jndiname に指定してください。以下は データソース <jndi-name> 名が "DefaultDS" である <xa-datasource> に対するリカバリマネージャの設定例です。

<property name="com.arjuna.ats.jta.recovery.XAResourceRecoveryJDBC"
          value="com.arjuna.ats.internal.jbossatx.jta.AppServerJDBCXARecovery;jndiname=DefaultDS"/>

上記 AppServerJDBCXARecovery リカバリモジュールは JMX Invoker を利用してデータベースから必要な情報を取得して、適切な javax.transaction.xa.XAResource を作成しリカバリを行います。従って、JMX Invoker がセキュリティで保護されている場合には、以下のように適切な認証ユーザー名とパスワードを指定する必要があります。

<property name="com.arjuna.ats.jta.recovery.XAResourceRecoveryJDBC"
          value="com.arjuna.ats.internal.jbossatx.jta.AppServerJDBCXARecovery;jndiname=DefaultDS,username=USER,password=PASS"/>

上記 JMX Invoker の "invoke" 操作に対するセキュリティ設定は、$JBOSS_HOME/server/$PROFILE/deploy/jmx-invoker-service.xmlorg.jboss.jmx.connector.invoker.AuthenticationInterceptorsecurityDomain 設定でなされています。デフォルトでは java:/jaas/jmx-console が設定されており $JBOSS_HOME/server/$PROFILE/conf/props/jmx-console-users.properties に定義されたユーザー名とパスワードでアクセス可能になっています。

なお、JBoss では同じ物理データベースサーバーに対して複数のデータソースを設定することができますが、この場合には、1 つのデータソースだけをリカバリするように設定する必要があります。リカバリマネージャによるリカバリは、データソース単位ではなくデータベースサーバー単位でなされます。同じデータベースにリカバリマネージャを設定した複数のデータソースがある場合、リカバリマネージャによるデータベースに対する検査が1回の処理で複数回検査されるため、リカバリが適切に行われなくなります。

各データベースベンダー固有の注意事項:
  • Oracle: XAトランザクションリカバリーを可能なアクセス件を許可する手順は、こちらの Knowledge "JBoss EAP で XA トランザクションリカバリ時の XAER_RMERR メッセージ" を参照してください。
  • PostgreSQL: Prepared トランザクション(つまり、XAトランザクション) を有効にする方法については、Web サイト を参照してください。JDBC ドライバーのバージョン 8.4-701 には org.postgresql.xa.PGXAConnection のバグがあります。これは、特定の状況でのリカバリを妨げます。CVS で修正が約束されていて、新しいバージョンのドライバーがダウンロードできます。ただし、最新のドライバー (9.0-801) には、特定の状況でリカバリを妨げる org.postgresql.xa.PGXAConnection の問題が見られます。詳細については、ここのスレッドを参照してください。
  • MySQL: MySQLのバグ情報 によると、XA トランザクションリカバリは可能ではありません。これについては JBoss EAP 5.1.0 リリースノートの 10. Known Issues に記載の JBPAPP-2576 でも言及されています。
  • DB2: DB2 は、XAResource.recover が呼び出されるのを、クラッシュ/失敗後にアプリケーションサーバーを再起動した際に発生する指定された再同期処理においてのみであることを期待しています。これは設計ミスですが、このドキュメントの範疇を越えるため、これについての詳細はここでは説明しません。

JMS リカバリ

重要な注意事項:
  • JMS XA リソースに対するトランザクションリカバリは、JBoss EAP 4.2 では利用できません。
  • このリカバリ設定は、EAP 4.3 CP04 以降から利用可能になっています。

JBoss Messaging XA リソースに対するリカバリマネージャを有効化してリカバリすることは非常に簡単です。以下の行を jbossjta-properties.xml/jbossjts-properties.xml に追加してください。

<property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.JBMESSAGING1"
          value="org.jboss.jms.server.recovery.MessagingXAResourceRecovery;java:/DefaultJMSProvider"/>

上の設定例では、リカバリマネージャが JMSProviderLoader "DefaultJMSProvider" を使用して、JMS XA リソースをリカバリしようと試みます。DefaultJMSProvider とはデフォルトの JMS プロバイダローダーであり、EAP 4.3 の $JBOSS_HOME/server/$PROFILE/deploy/*jms-ds.xml、EAP 5 の $JBOSS_HOME/server/$PROFILE/deploy/messaging/jms-ds.xml に定義されています。別の JMSProviderLoader (たとえば、リモートの JMS プロバイダに対応するもの) を使用してリカバリを行うには、別の行を追加して DefaultJMSProvider ではなくリモートの JMS プロバイダの名前(リモートの JMS プロバイダの MBean 設定に定義されている名前) を指定してください。

なお、リカバリマネージャを複数定義する場合、各リカバリモジュールの "name" はユニークにする必要があります。

<property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.JBMESSAGING2"
          value="org.jboss.jms.server.recovery.MessagingXAResourceRecovery;java:/RemoteJMSProvider"/>

JMS プロバイダがセキュリティ保護されている場合は、認証情報を以下のように渡してください。

<property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.JBMESSAGING1"
          value="org.jboss.jms.server.recovery.MessagingXAResourceRecovery;java:/DefaultJMSProvider,USER,PASS"/>
JMS クラスターのメモ

JBoss Messaging クラスタのうちの 1 つのノードがダウンすると、クラスタ内の相手のノードがそれを検知して、データベースからダウンしたサーバーのメッセージをすべてロードします。

ダウンしたノードがダウン時に XA トランザクションを実行している場合は、トランザクションログが書き込まれますが、関連するメッセージはクラスタの別のサーバーに移動します。

ダウンしたサーバーがリカバリすると、リカバリマネージャーがトランザクションログに保存されたトランザクションを回復しようとします。メッセージが別のサーバーに移動していると、ローカルの JMS プロバイダから適切な XAResource を獲得することができなくなります。これは、関連メッセージがそのサーバーにはすでに存在していないからです。そして、そのとき JBossTS は以下のようなログを出力します。

Could not find new XAResource to use for recovering non-serializable XAResource

これを解決するには、クラスタの各ノードに対応する JMS プロバイダとリカバリマネージャを追加する必要があります。たとえば、クラスタにノードが 3 つある場合は、以下のように自ノード以外の JMS プロバイダに対するリカバリ設定をを jbossjta-properties.xml/jbossjts-properties.xml に追加してください。

<property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.JBMESSAGINGREMOTE1"
          value="org.jboss.jms.server.recovery.MessagingXAResourceRecovery;java:/RemoteJMSProvider1"/>

<property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.JBMESSAGINGREMOTE2"
          value="org.jboss.jms.server.recovery.MessagingXAResourceRecovery;java:/RemoteJMSProvider2"/> 

リモードプロバイダ設定は、以下のようなものを、EAP 4.3 であれば $JBOSS_HOME/server/$PROFILE/deploy/*jms-ds.xml に、EAP 5 であれば $JBOSS_HOME/server/$PROFILE/deploy/messaging/jms-ds.xml に追加してください。

  <mbean code="org.jboss.jms.jndi.JMSProviderLoader"
     name="jboss.jms:service=JMSProviderLoader,name=RemoteJMSProvider1">
    <attribute name="ProviderName">RemoteJMSProvider1</attribute>
    <attribute name="ProviderAdapterClass">org.jboss.jms.jndi.JNDIProviderAdapter</attribute>
    <attribute name="FactoryRef">XAConnectionFactory</attribute>
    <attribute name="QueueFactoryRef">XAConnectionFactory</attribute>
    <attribute name="TopicFactoryRef">XAConnectionFactory</attribute>
    <attribute name="Properties">
       java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
       java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
       java.naming.provider.url=RemoteHost1:1099
    </attribute>
  </mbean>  <mbean code="org.jboss.jms.jndi.JMSProviderLoader"
     name="jboss.jms:service=JMSProviderLoader,name=RemoteJMSProvider2">
    <attribute name="ProviderName">RemoteJMSProvider2</attribute>
    <attribute name="ProviderAdapterClass">org.jboss.jms.jndi.JNDIProviderAdapter</attribute>
    <attribute name="FactoryRef">XAConnectionFactory</attribute>
    <attribute name="QueueFactoryRef">XAConnectionFactory</attribute>
    <attribute name="TopicFactoryRef">XAConnectionFactory</attribute>
    <attribute name="Properties">
       java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
       java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
       java.naming.provider.url=RemoteHost2:1099
    </attribute>
  </mbean>

JNDI プロパティはリモートサーバー (つまり、クラスタにあるその他のノード) に接続するために設定されます。適切なリカバリーを取得するために、クラスタの他のすべてのノードに対して、クラスタの各ノードにプロバイダおよびリカバリーマネージャーを追加してください。

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.

Comments