グローバル トランザクションに参加する JAX-WS サービスのデモを作成しようとしています。これは、時間が経つにつれて私の組織がより多くのことを行うモデルであり、それを理解する必要がありますが、私は苦労しています.
クライアントから呼び出されている WSDL サービスがあります (これは同じ構成の Java EE サーブレットにもあります...実際には同じサーバーですが、ネットワークを介してそれ自体を呼び出していることがわかります)。両方とも行を更新してから例外をスローしますが、サービスはロールバックしません。
ローカル DAO 更新と WSDL サービス クライアントの両方を呼び出すメソッドに @Transactional(propagation=Propagation.REQUIRED) という注釈を付けました。そのサービスは、同じ方法でアノテーションが付けられた別のメソッドを呼び出します。このメソッドは、dao メソッドを呼び出して別のデータベース更新を行います。
app-config.xml:
<jee:jndi-lookup id="wsdlDataSource" jndi-name="${es.ds.jndi}" />
<bean id="wsdlSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="wsdlDataSource" />
<property name="packagesToScan" value="com.wsdl" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.DB2Dialect</prop>
<prop key="hibernate.connection.driver_class">com.ibm.db2.jcc.DB2Driver</prop>
<prop key="hibernate.bytecode.provider">javassist</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.default_schema">k702prdr</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop>
<prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</prop>
<prop key="jta.UserTransaction">java:comp/UserTransaction</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.wsdl.db.DBTrans</value>
<value>com.wsdl.db.UsrTrans</value>
</list>
</property>
</bean>
<!-- END Data sources -->
<!-- BEGIN Hibernate config and dependencies -->
<bean id="transactionManager"
class="org.springframework.transaction.jta.WebSphereUowTransactionManager" >
</bean>
<tx:annotation-driven transaction-manager="transactionManager"
proxy-target-class="true" />
[サービス] ビューに移動し、WSTRansaction ポリシー セットとバインディングをクライアントとサービス (両方とも最初に RAD ウィザードから生成) に追加し、次に再び管理コンソール アプリケーション -> アプリケーション タイプ -> に追加するいくつかのチュートリアルに従いました。 Websphere エンタープライズ アプリ -> マイ アプリ -> サービス プロバイダー/クライアント ポリシー セットおよびバインディング。そこで、親アプリケーション レベルでクライアントとサービスにそれぞれ WSTransaction を追加しました (ポリシーはエンドポイントまで継承されます)。
しかし、結局のところ、ロールバックは発生していません。ヘルプ!私は何が欠けていますか?何を誤って構成しましたか?
(更新) - 管理コンソールで websphere トランザクション追跡ログを有効にする方法を見つけました。それは言います(簡潔にするために編集されています):
No transaction context found
Exit
Entry parm0=Operation: isAlive
No transaction context from incoming request
getTransactionManager parm0=com.ibm.ws.tx.jta.TranManagerSet@306e306e
これらのメッセージには、オブジェクトの検査のように見える一連のメッセージが含まれており、何度も繰り返されます。さて、クライアントからトランザクション コンテキストを送信していないようです。しかし、私はまだ理由を理解していません。誰?
(更新 2) - サービスとクライアントの WSTRansaction ポリシー セットが共有に設定されていないことを発見したので、wsdl を介して共有するように設定しました。トレース ログは、トランザクション コンテキストを見つけていることを示しているようです。 .または少なくとも、上記のようにできないと明示的に言っているわけではありません。次のようないくつかのことを言っていますが、それは私が考えていることを意味するかもしれないし、意味しないかもしれません (繰り返しますが、あなたが見ていない意味のある何かがある場合は簡潔にするために編集してください、教えてください、そこにはもっと多くの情報があります):
Entry parm0=XATransactionWrapper@ 5f175f17 XAResource: com.ibm.ws.rsadapter.spi.WSRdbXaResourceImpl@5b7d5b7d enlisted: falseHas Tran Rolled Back = false mcWrapper.hashCode()490085686 parm1=XARESOURCE_NOTASSOCIATED
xa_start with flag: 0=TMNOFLAGS
setResourceStatus parm0=from NONE to REGISTERED
[at this point I see a log stmt that indicates my first update in the service]
setResourceStatus parm0=from REGISTERED to COMPLETING_ONE_PHASE
**setResourceStatus parm0=from COMPLETING_ONE_PHASE to COMMITTED**
setResourceStatus parm0=from NONE to REGISTERED
[at this point I see a log stmt that indicates my second update, which is done in the client]
setResourceStatus parm0=from REGISTERED to COMPLETING
setResourceStatus parm0=from COMPLETING to ROLLEDBACK
[at this point I see the stack trace of the hardcoded exception I am throwing]
したがって、トランザクション マネージャーはクライアントとサービス トランザクションの両方を認識しているにもかかわらず、その部分が完了したらすぐにサービス側でトランザクションを完了する必要があると考え、続行する必要があることに気付いていないことは明らかです。どういうわけか、時期尚早のコミットを引き起こしたと思います。アイデア?