Xmlファイルの代わりに@Configuration
注釈をspringの構成に使用しています。異なるセッションファクトリと異なるトランザクションマネージャーで2つのデータソースを構成しています。ここで@EnableTransactionManagement
アノテーションの問題に悩まされています。私はその文書を読んで、
@EnableTransactionManagement
はより柔軟です。コンテナ内のPlatformTransactionManager
Beanのタイプ別ルックアップにフォールバックします。したがって、名前は「txManager」、「transactionManager」、または「tm」になります。単に問題ではありません。
これは、メソッドに付ける名前に関係なく、トランザクションマネージャーが2つある間は常にPlatformTransactionManager
オブジェクトを返すメソッドを検索します。問題は、このクラスをテストするとエラーが発生することです。
org.springframework.beans.factory.NoSuchBeanDefinitionException
:タイプ[org.springframework.transaction.PlatformTransactionManager
]の一意のBeanは定義されていません:予期される単一のBeanが見つかりました2
2つの異なる構成クラスを作成しようとしましたが、無駄でした。 xml構成では、そうではありませんでした。 2つの<tx:annotation-driven transaction-manager="" />
タグで両方のトランザクションマネージャーを登録しましたが、正常に機能しました。ただし、ここではアノテーションを使用して同じことを行うことはできません。
Spring注釈付き構成クラスで2つの異なるトランザクションマネージャーで2つのデータソースを構成する場合はどうすればよいですか?
構成クラスで、@EnableTransactionManagement
注釈を使用します。
このクラスでトランザクションマネージャを次のように定義します。
@Bean(name="txName")
public HibernateTransactionManager txName() throws IOException{
HibernateTransactionManager txName= new HibernateTransactionManager();
txName.setSessionFactory(...);
txName.setDataSource(...);
return txName;
}
その上で、トランザクションジョブを実行するクラス/メソッドで、次のように注釈を付けます。
@Transactional("txName")
または
@Transactional(value = "txName")
これは、必要な場所に名前修飾トランザクションマネージャを結び付ける方法です。これで、必要な数のトランザクションマネージャを作成し、必要に応じて使用できます。
誰かがこの問題に遭遇した場合に備えて、解決策を見つけました:
@Configuration
@EnableTransactionManagement
@DependsOn("myTxManager")
@ImportResource("classpath:applicationContext.xml")
public class AppConfig implements TransactionManagementConfigurer {
@Autowired
private PlatformTransactionManager myTxManager;
...
@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
return this.myTxManager;
}
このようにして、xml構成で定義された特定のtxManagerを使用できます。
サービスレベルで使用されるtxManagerを定義する場合、removeからの@EnableTransactionManagement
アノテーション@Configuration
クラスと@Transactional
アノテーションでtxManagerを指定します。例えば.
@Service
@Transactional(value="myTxManager", readOnly = true)
public class MyServiceImpl implements MyService { ... }
Java doc から
より直接的な関係を確立したい方のために
@EnableTransactionManagement
および使用する正確なトランザクションマネージャBean、TransactionManagementConfigurer
コールバックインターフェイスを実装できます-implements句と@Override
-以下の注釈付きメソッド:
きみの @Configuration
クラスはTransactionManagementConfigurer
インターフェイスを実装する必要があります-使用するannotationDrivenTransactionManager
への参照を返すtransactionManager
を実装します。
2つのTransactionManagerを使用している理由がわかりません。 AbstractRoutingDataSourceを介して、複数のデータソースに同じTransactionManagerを使用することを検討できます。ご参照ください
http://blog.springsource.org/2007/01/23/dynamic-datasource-routing/
その使用法のサンプル。
他の回答のいくつかは、2つのトランザクションマネージャーを使用することが何らかの形で間違っていることを暗示しています。ただし、SpringのXML構成では、オンラインドキュメント(下記)に記載されているように、複数のトランザクションマネージャーを使用できます。残念ながら、@EnableTransactionManagement
アノテーションを同様の方法で機能させる方法はないようです。その結果、@ImportResource
アノテーションを使用して、<tx:annotation-driven/>
行を含むXMLファイルをロードするだけです。これにより、ほとんどの場合にJava構成を取得できますが、オプションのTransaction Manager修飾子とともに@Transactional
を引き続き使用できます。
http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/transaction.html
ほとんどのSpringアプリケーションに必要なトランザクションマネージャーは1つだけですが、単一のアプリケーションに複数の独立したトランザクションマネージャーが必要な場合があります。
@Transactional
アノテーションのvalue属性を使用して、使用するPlatformTransactionManager
のIDをオプションで指定できます。これは、トランザクションマネージャBeanのBean名または修飾子値のいずれかです。たとえば、修飾子表記を使用すると、次のJavaコード
chained TransactionalManagerを使用してみてください
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.transaction.ChainedTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
@Configuration
public class ChainedDBConfig {
@Bean("chainedTransactionManager")
public PlatformTransactionManager transactionManager(
@Qualifier("database1TransactionManager") final PlatformTransactionManager db1PlatformTransactionManager,
@Qualifier("database2TransactionManager") final PlatformTransactionManager db2PlatformTransactionManager) {
return new ChainedTransactionManager(db1PlatformTransactionManager, db2PlatformTransactionManager);
}
}
そして、次の注釈をサービスクラスに配置します。
@Transactional(transactionManager = "chainedTransactionManager")
public class AggregateMessagesJobIntegrationTest {
...
}
統合テスト内でも使用できます。
@RunWith(SpringRunner.class)
@Transactional(transactionManager = "chainedRawAndAggregatedTransactionManager")
@Rollback
public class ExampleIntegrationTest extends AbstractIntegrationTest {
....
}
また、両方のDBトランザクションマネージャーに対してロールバックを実行します。