12

1 つの applicationContext.xml ファイルがあり、Spring ミドルウェア カスタム アプリケーションで構成された 2 つの org.springframework.orm.jpa.JpaTransactionManager (それぞれが独自の永続ユニット、異なるデータベースを持つ) があります。

TransactionStatus のコミット、保存、およびロールバックをいじらないように、アノテーション ベースのトランザクション (@Transactional) を使用したいと考えています。

同僚は、複数のトランザクション マネージャーがあると、コンテキスト ファイルが正しく構成されていても、これを行うと何かが混乱すると言っていました (参照は正しい永続化ユニットに移動します)。誰か問題を見たことがありますか?


あなたの構成では、2 つのトランザクション マネージャーがありますか? txManager1 と txManager2 はありますか?

それが、トランザクション マネージャーである 2 つの異なる Spring Bean である JPA で私が持っているものです。

4

2 に答える 2

10

私はあなたが2つの選択肢を持っていると思います

ユースケースで同じトランザクション内で両方のデータベースを更新する必要がない場合は、2 つの JpaTransactionManager を使用できますが、@Transactional アプローチを使用できるかどうかはわかりません。この場合、単純なTransactionProxyFactoryBeanを使用してトランザクション境界を定義する古いメカニズムにフォールバックする必要があります。

<bean id="firstRealService" class="com.acme.FirstServiceImpl"/>
<bean id="firstService"  
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="firstJpaTm"/>
    <property name="target" ref="firstRealService"/>
    <property name="transactionAttributes">
        <props>
           <prop key="insert*">PROPAGATION_REQUIRED</prop>
           <prop key="update*">PROPAGATION_REQUIRED</prop>
           <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
        </props>
    </property>
</bean>
<!-- similar for your second service -->

両方のデータベースにまたがるトランザクションが必要な場合は、JTA トランザクション マネージャーを使用する必要があります。APIは次のように述べています。

このトランザクション マネージャーは、単一の JPA EntityManagerFactory をトランザクション データ アクセスに使用するアプリケーションに適しています。JTA (通常は JtaTransactionManager を介して) は、同じトランザクション内の複数のトランザクション リソースにアクセスするために必要です。JPA プロバイダーを JTA トランザクションに参加させるには、それに応じて JPA プロバイダーを構成する必要があることに注意してください。

つまり、JTA トランザクション マネージャーを用意する必要があります。このアプリケーションでは、次のような構成を使用します。

<tx:annotation-driven transaction-manager="txManager"/>

<bean id="txManager" 
    class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="transactionManagerName" value="appserver/jndi/path" />
</bean>

アプリサーバー内にデプロイする場合、Spring JtaTransactionManager は、アプリサーバーによって提供される実際の XA 準拠の JTA トランザクション マネージャーを参照する必要があります。ただし、スタンドアロンの JTA トランザクション マネージャーを使用することもできます (ただし、私自身はまだ試していません)。

Jpa 永続化プロバイダーの構成に関しては、私はあまり詳しくありません。どの JPA 永続化プロバイダーを使用していますか?

上記のコードは、Hibernate の JPA 実装ではなく、ネイティブの Hibernate を使用したアプローチに基づいています。この場合、2 つの HibernateTransactionManager Bean を取り除き、両方の SessionFactories に同じ JTA TM が注入されていることを確認してから、tx:annotation-driven 要素を使用することができました。

お役に立てれば

于 2008-09-16T23:56:40.503 に答える
4

2つのSpringトランザクションマネージャーを使用できる唯一の状況は、一度に両方のトランザクションを開いたことがない場合です。これは本質的に分散トランザクションとは関係ありません。2つのデータソースに完全に分離した(ただし、時間的に重複する可能性がある)トランザクションライフサイクルが必要な場合でも、同じ制限が適用されます。

内部的には、SpringのトランザクションマネージャーはすべてSpringのTransactionSynchronizationManagerを使用しており、静的ThreadLocal変数に一連の重要な状態を保持するため、トランザクションマネージャーは互いの状態全体を踏みにじることが保証されます。

于 2008-11-11T13:30:50.833 に答える