如何使用Spring + DBUnit + JUnit配置多个事务管理器

简而言之

我的命令行Java应用程序无需使用XA就可以将数据从一个数据源复制到另一个数据源。我已经配置了两个单独的数据源,并且想要一个可以在两个数据源上回滚数据的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上的事务管理器,因为它将是只读的。这个问题仅适用于我的测试班。

回答:

可能的解决方法是引入一个注释为的辅助bean,@Transactional("transactionManagerTarget")而将测试保留为@Transactional("transactionManager"),同时使用进行配置defaultRollback = true。然后,您的测试将不得不调用助手bean,而后者又将调用被测试的服务bean。这将导致服务周围的事务回滚,然后DBUnit周围的事务回滚。

不过,这有点混乱。

其他可能的方法:

  • 使用内存数据库(例如H2)而不是生产数据库-您可以将其配置为在需要时删除其所有数据。
  • 允许DBUnit提交,并在您的拆卸方法中进行补偿事务以清除数据。

以上是 如何使用Spring + DBUnit + JUnit配置多个事务管理器 的全部内容, 来源链接: utcz.com/qa/409088.html

回到顶部