5

手短に

私のコマンド ライン Java アプリケーションは、XA を使用せずに、あるデータ ソースから別のデータ ソースにデータをコピーします。2 つの別個のデータソースを構成しており、両方のデータソースのデータをロールバックできる JUnit テストが必要です。DBUnit を使用して「ソース」データベースにデータをロードしましたが、これをロールバックできません。「ターゲット」データソースをロールバックすることができます。

マイコード

この構成を考えると...

<tx:annotation-driven />

<!-- note the default transactionManager name on this one -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource"     ref="dataSourceA" />
</bean>

<bean id="transactionManagerTarget" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource"     ref="dataSourceB" />
</bean>

そしてこのコード...

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:resources/spring-context.xml",
                                "classpath:resources/spring-db.xml"})  
@Transactional
@TransactionConfiguration(transactionManager = "transactionManagerTarget", defaultRollback = true) 
public class MyIntegrationTest {

    @Autowired
    private MyService service;

    @Autowired
    @Qualifier("dataSourceA")
    private DataSource dataSourceA;

    private IDataSet loadedDataSet;

    /**
     * Required by DbUnit
     */
    @Before
    public void setUp() throws Exception {
        SybaseInsertIdentityOperation.TRUNCATE_TABLE.execute(getConnection(), getDataSet());
        SybaseInsertIdentityOperation.INSERT.execute(getConnection(), getDataSet());
    }

    /**
     * Required by DbUnit
     */
    protected IDataSet getDataSet() throws Exception {
        loadedDataSet = DbUnitHelper.getDataSetFromFile(getConnection(), "TestData.xml");
        return loadedDataSet;
    }

    /**
     * Required by DbUnit
     */
    protected IDatabaseConnection getConnection() throws Exception{
        return new DatabaseConnection(dataSourceA.getConnection());
    }   

    @Test
    public void testSomething() {

        // service.doCopyStuff();

    }

}

私が見ている問題は@TransactionConfiguration、ロールバックを有効にするためのターゲットデータソースのみを示していることです。DBUnit はdataSourceA明示的に渡さtransactionManagerれており、ロールバックするように指示されていない (方法はわかりません) という名前のデフォルトのトランザクション マネージャーを取得しています。

質問

両方のトランザクション マネージャーにロールバックするように指示するにはどうすればよいですか?

データソースが XA トランザクションをサポートしていない場合、単一のトランザクション マネージャーを使用できますか?

注: アプリケーションは、読み取り専用であるため、本番環境で実行する場合、dataSourceA にトランザクション マネージャーを必要としません。この問題は、私のテスト クラスのみに適用されます。

4

3 に答える 3

1

オープンソースのTMAtomikosを使用したJUnitテストでXAトランザクションとロールバックを使用しました。優れた機能の1つは、Atomikosを使用すると、XAに対応していないデータソースを使用してXAトランザクションに参加できることです。例については、次のリンクを確認してください:http ://www.atomikos.com/Documentation/NonXaDataSource

一方、XAがJUnitの問題に対する適切なソリューションである場合は、別の話になります。テストはデータベースの実装(Sybase)に重点を置いていますか、それともJavaロジックに重点を置いていますか?私は通常、JUnitテスト用にApacheDerbyやHQSQLなどの組み込みDBをセットアップします。その後、GCがそれを処理するので、クリーンアップについてあまり気にする必要はありません:)

于 2012-05-18T21:48:47.483 に答える
1

<qualifier>トランザクション マネージャー定義内の要素を使用します。

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSourceA" />
    <qualifier value="transactionManager" />
</bean>

<bean id="transactionManagerTarget" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSourceB" />
    <qualifier value="transactionManagerTarget" />
</bean>

@Transactional次に、注釈で直接使用するものを参照できます。つまり、

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:resources/spring-context.xml",
                                "classpath:resources/spring-db.xml"})  
@Transactional("transactionManagerTarget")
@TransactionConfiguration(defaultRollback = true) 
public class MyIntegrationTest {
...
于 2012-05-18T12:49:13.717 に答える
0

考えられる回避策は、 として注釈が付けられたヘルパー Bean を導入し、@Transactional("transactionManagerTarget")テストに として注釈を付けたままにし@Transactional("transactionManager")、両方を で構成することdefaultRollback = trueです。次に、テストはヘルパー Bean を呼び出す必要があり、ヘルパー Bean はテスト対象のサービス Bean を呼び出します。これにより、サービスに関するトランザクションがロールバックされ、次に DBUnit に関するトランザクションがロールバックされます。

ただし、少し面倒です。

他の可能なアプローチ:

  • 実稼働データベースの代わりに H2 などのインメモリ データベースを使用すると、必要に応じてすべてのデータを削除するように構成できます。
  • DBUnit がコミットできるようにし、ティアダウン メソッドで補正トランザクションを使用してデータを消去します。
于 2012-05-19T10:55:24.647 に答える