目的
以前に作成した Resource Adapterにトランザクション機能を追加してトランザクションのテストをします。
で使用したものです。
コードの変更
追加下コードが以下の commit です。
ra.xml の XATransactionの追加
<?xml version="1.0" encoding="UTF-8"?>
<connector id="Connector_ID" version="1.7"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/connector_1_7.xsd">
<description></description>
<display-name>Pdprof Resource Adapter</display-name>
<vendor-name>PDPROF</vendor-name>
<eis-type></eis-type>
<resourceadapter-version>20251028</resourceadapter-version>
<resourceadapter>
<resourceadapter-class>pdprof.ra.PdprofResourceAdapter</resourceadapter-class>
<outbound-resourceadapter>
<connection-definition>
<managedconnectionfactory-class>pdprof.ra.PdprofManagedConnectionFactory</managedconnectionfactory-class>
<connectionfactory-interface>pdprof.ra.PdprofConnectionFactory</connectionfactory-interface>
<connectionfactory-impl-class>pdprof.ra.PdprofConnectionFactoryImpl</connectionfactory-impl-class>
<connection-interface>pdprof.ra.PdprofConnection</connection-interface>
<connection-impl-class>pdprof.ra.PdprofConnectionImpl</connection-impl-class>
</connection-definition>
<transaction-support>XATransaction</transaction-support>
</outbound-resourceadapter>
</resourceadapter>
</connector>
以下のクラスの追加
package pdprof.ra;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
public class PdprofXAResource implements XAResource {
...
}
ManagedConnectionのクラス getXAReource() で 返すように値を返す様に変更
public XAResource getXAResource() throws ResourceException {
// throw new NotSupportedException("GetXAResource not supported");
return this.xaResource;
}
この変更以外にトランザクションの動作を確認するためのログを追加しました。
環境の構築
docker で環境を構築します。
git clone https://github.com/pdprof/resource-adapter.git
cd resource-adapter/resource-adapter-docker
./setup-docker.sh
Libertyを起動します。
./start.sh
Resource Adapter の動作を確認
Resource AdapterとTransactionの動作が問題ないかアクセスして、ログを確認します。以下は localhost にアクセスするときのURLです。
トランザクションの処理時間のうち以下のものを変更できます。
- sleepTime, transaction begin から commit の間の時間
- prepareTime, prepare 開始後、prepare 終了までの時間
- commitTime, commit 開始後、commit 完了までの時間
先ほどのアクセスをしたと時は以下のログが確認できます。
> HelloServlet.doGet start
= HelloServlet.doGet call > ut.begin()
= HelloServlet.doGet called < ut.begin()
= HelloServlet.doGet call > sleep time in ms = 0
= HelloServlet.doGet called < sleep
= PdprofXAResource.start - 1463898948 flags = 0
= PdprofConnectionImpl.hello()
= PdprofXAResource.start - 1463898948 flags = 0
= PdprofConnectionImpl.hello(msg)
= HelloServlet.doGet call > ut.commit()
= PdprofXAResource.end - 1463898948 flags = 67108864
= PdprofXAResource.end - 1463898948 flags = 67108864
> PdprofXAResource.prepare start (sleep time in ms = 0)
< PdprofXAResource.prepare end id = 1463898948
> PdprofXAResource.prepare start (sleep time in ms = 0)
< PdprofXAResource.prepare end id = 1463898948
> PdprofXAResource.commit start (sleep time in ms = 5000)
< PdprofXAResource.commit end id = 1463898948 isOnePhase = false
> PdprofXAResource.commit start (sleep time in ms = 5000)
< PdprofXAResource.commit end id = 1463898948 isOnePhase = false
= PdprofConnectionImpl.close()
= PdprofConnectionImpl.close()
= HelloServlet.doGet called < ut.commit()
< HelloServlet.doGet end
PdprofXAResource.commit 処理中の障害発生
PdprofXAResource.commit中に問題が発生してcommitが完了しなかった場合の問題を発生させます。(kill -9 もしくは docker stop -t 1 resource-adapter でサーバーを停止させます。)
でアクセスして、commit で 20秒時間がかかっている時にプロセスを停止します。docker logs -f resource-adapter でログを見て動作状況を確認します。
サーバーの再起動をし、次に同じリクエストをさせてトランザクションの処理があったところでトランザクションのリカバリーも実施されました。再起動時にリカバリーが実施されるtWASとは動作が違うようです。
[1/29/26 15:39:22:992 UTC] 00000043 com.ibm.ws.recoverylog.spi.RecoveryDirectorImpl I CWRLS0012I: All persistent services have been directed to perform recovery processing for this WebSphere server (defaultServer).
[1/29/26 15:39:22:992 UTC] 0000004d com.ibm.tx.jta.impl.RecoveryManager A WTRN0027I: Transaction service recovering 1 transaction.
[1/29/26 15:39:23:080 UTC] 0000004d SystemOut O = PdprofXAResource.recover
[1/29/26 15:39:23:093 UTC] 0000004d SystemOut O = PdprofXAResource.recover
[1/29/26 15:39:23:133 UTC] 0000004d SystemOut O > PdprofXAResource.commit start (sleep time in ms = 0)
[1/29/26 15:39:23:134 UTC] 0000004d SystemOut O < PdprofXAResource.commit end id = 1463898948 isOnePhase = false
[1/29/26 15:39:23:138 UTC] 0000004d SystemOut O > PdprofXAResource.commit start (sleep time in ms = 0)
[1/29/26 15:39:23:139 UTC] 0000004d SystemOut O < PdprofXAResource.commit end id = 1463898948 isOnePhase = false
確認したところ以下のサイトに書いてありました。
デフォルトでは、サーバー障害後のトランザクション・リカバリーは、サーバー始動時ではなく、トランザクシ>ョン・サービスが最初に使用されたときに行われます。
時間がかかる処理を変更して、障害発生時の処理状況を変えることで動作の違いを確認できます。ut.commit() 前だとリカバリー対象のトランザクションがないものとしてログされていました。
[1/29/26 15:51:46:310 UTC] 0000004d com.ibm.tx.jta.impl.RecoveryManager I WTRN0135I: Transaction service recovering no transactions.
[1/29/26 15:51:46:380 UTC] 0000004d SystemOut O = PdprofXAResource.recover
[1/29/26 15:51:46:394 UTC] 0000004d SystemOut O = PdprofXAResource.recover
トラブルシューティング
毎度のことですが、よくつかう dockerコマンドを書いておきます。この文書でもpodman, dockerとまとまりがないですが、Linux では dockerがpodmanを呼び出すようになっていました。
docker ps # 動作中のContainer確認
docker logs -f resource-adapter # ログ確認
docker restart resource-adapter # 再起動
docker inspect resource-adapter # container 確認
docker exec -it resource-adapter bash # Container内状況確認
dcoker stop -t 1 resource-adapter # 1秒後に強制停止
まとめ
トランザクションの処理とリソースのリカバリーについてテストしました。