春季交易没有回滚

时间:2012-08-20 17:17:23

标签: spring transactions junit dbunit

我一直在处理JUnit Testing的项目中使用spring transactional management。我已经让这个工作正常,我的JUnit测试,但我不能让它在那之外工作。这是我的基本情景:

我有一个处理DbUnit Initialization的类,类似于:

@TransactionConfiguration( defaultRollback = true )
@Transactional(propagation=Propagation.REQUIRED)
public class DbUnitManagerImpl implements DbUnitManager {

    @Override
    public void initializeDatabase(String location) {
        // Does work to create a dataset from the file at location

        // Calls a function within this class to execute the dbUnit initialization
        runSetUp()
    }

    public void runSetUp() {
       // Executes dbUnit call to initialize database
    }
}

我在两个不同的实例中使用此类。我在运行JUnit测试时使用它来初始化数据,我也从Backing Bean中为网页调用这些函数。

JUnit设置将正确回滚,如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/context/applicationContext-rdCore.xml" })
@TransactionConfiguration( defaultRollback = true )
@Transactional(propagation=Propagation.REQUIRED)
public abstract class BaseDatabaseTest {

    @Autowired private DbUnitManager dbUnitManager;

    @Test
    public void runTest1() {
        dbUnitManager.initializeDatabase("D:\\test.xml");
    }
}

我的支持bean以类似的方式工作,但它允许DbUnitManagerImpl执行所有事务。我已调试使用以下命令启动事务:

System.out.println(TransactionSynchronizationManager.isActualTransactionActive());

在这两种情况下都会显示true,表明正在启动事务,但只有JUnit测试才会发生回滚。支持bean看起来像这样:

@Service
@SessionScoped
public class DbUnitInitializerBean {

    @Autowired private DbUnitManager manager;

    /**
     * Initializes the database using the files at <code>location</code>
     */
    public void initializeDatabase() {
        manager.initializeDatabase("D:\\test.xml);
    }
}

一些注意事项: 上面提到的三个类别显然被剥夺了。它们还驻留在三个不同的Java项目中。支持bean驻留在具有以下应用程序上下文的Web项目中:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:cache="http://www.springframework.org/schema/cache" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
         http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

    <context:annotation-config />
    <cache:annotation-driven />
    <context:component-scan base-package="com.nph.rd.dbunit" />

    <import resource="classpath:/context/applicationContext-rdCore.xml"/>
</beans>

我的测试项目的应用程序上下文包含DbUnitManagerImpl类,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:cache="http://www.springframework.org/schema/cache" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
         http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

    <context:annotation-config />
    <cache:annotation-driven />


    <import resource="classpath:/context/applicationContext-rdCore.xml"/>

</beans>

主应用程序上下文驻留在包含我的JUnit测试的项目中,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:cache="http://www.springframework.org/schema/cache" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
         http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

    <context:annotation-config />
    <tx:annotation-driven />

    <context:component-scan base-package="com.nph.rd.dbunit" />
    <context:component-scan base-package="com.nph.dbunit" />

    <bean id="dbUnitManager" class="com.nph.dbunit.dao.impl.DbUnitManagerImpl">
    </bean>

    <!-- allows for ${} replacement in the spring xml configuration from the .properties file on the classpath -->
    <context:property-placeholder location="classpath:/properties/core-system.properties" ignore-unresolvable="true"/>

    <!-- Transaction Manager -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!-- OLTP data source -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${oltp.database.driverClassName}" />
        <property name="url" value="${oltp.database.url}" />
        <property name="username" value="${oltp.database.username}" />
        <property name="password" value="${oltp.database.password}" />
    </bean>

</beans>

基本的最终目标是,我将让我的DbUnitManager类在从Backing Bean中使用它时能够在异常基础上回滚,但无论从我的JUnit测试中使用什么,它都会回滚。目前我将DbUnitManager类设置为始终回滚,因为我试图让事务回滚一般工作。在我开始工作之后,我会将其移动到异常基础上回滚。

1 个答案:

答案 0 :(得分:0)

从DbUnitManagerImpl中删除以下内容

 @TransactionConfiguration( defaultRollback = true )

此注释仅适用于Spring TestRunner。默认情况下,Spring TestRunner将回滚所有事务,因此您可以使用@TransactionConfiguration覆盖该行为。

如果您正在使用Spring TransactionManager(它是),它将自动回滚未捕获的运行时异常。如果要回滚已检查的异常,可以在@Transactional注释中指定它们或将它们转换为运行时注释。

 @Transactional(rollbackFor = SomeCheckedException.class)
 public void someMethod() {}