【问题标题】:Transaction management doesn't appear to work on Spring Tests事务管理似乎不适用于 Spring 测试
【发布时间】:2016-03-30 19:12:43
【问题描述】:

我希望在使用@Transactional 的方法完成后将数据写入数据库。在使用 HSQL 数据库时,这是我的 JUnit 测试的有效假设吗?我使用 HSQL db 进行开发,使用 Oracle 进行部署的应用程序。 Web App 部署在 WebSphere 上,使用 RSA 开发。 下面是我的配置总结,包括 POM 和 junit 测试:

POM:
3.2.9.RELEASE
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.3</version>

<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.1</version>

APPLICATION CONTEXT:
<!-- the bean for transaction manager for scoping/controlling the transactions -->
<bean id="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dbDataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

<jee:jndi-lookup id="dbDataSource" jndi-name="jndi/HSQLDatasource" expected-type="javax.sql.DataSource" />

<!--Mapper-->
<bean id="campaignMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
    <property name="mapperInterface"
        value="com.abc.persistence.mapper.CampaignMapper" />
    <property name="sqlSessionTemplate">
        <bean class="org.mybatis.spring.SqlSessionTemplate">
            <constructor-arg index="0" ref="sqlSessionFactoryForBatch" />
            <constructor-arg index="1" value="BATCH" />
        </bean>
    </property>     
</bean>

<!-- SqlSessionFactory For Batch -->
<bean id="sqlSessionFactoryForBatch" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dbDataSource" />
    <property name="typeAliasesPackage" value="com.abc" />
    <property name="mapperLocations" value="classpath*:com/mybatis/mappers/**/*.xml" />
</bean>

JUNIT:
//junit class extends a base class that initializes HSQL db
//jdbcConnection.setAutoCommit(false);

    @Autowired
    CampaignMapper campaignMapper;

    @Transactional
    @Test 
    public void testInsert(){

        for(Campaign record:campaignsFromFile){
            record.setRowLastUpdateId(rowLastUpdateId);
            record.setCampaignId(campaignId);
            campaignMapper.insertCampaignRecord(record);
        }
        //At this point I expect that the data would NOT be written to the database
        //other method code

        }//end of method
        //At this point I expect that the data would be written to the database

【问题讨论】:

    标签: java spring hsqldb spring-test spring-mybatis


    【解决方案1】:

    默认情况下,Spring 会在测试上下文中回滚事务。如果这不是您期望的行为,您始终可以使用 @Rollback 注释和 false 值:

    @Transactional
    @Test 
    @Rollback(false)
    public void testInsert() { ... }
    

    如果您使用的是 Spring 4.2.x 版本,则可以使用新的 @Commit 注释,这是一个可以直接替代 @Rollback(false) 的新注释。您可以在 Spring 测试上下文 here 中阅读有关 事务管理 的更多信息。

    【讨论】:

    • 我的期望是在方法退出之前不应将记录写入数据库。但是,如果我在调试中运行,在插入后放置一个断点并在每次插入后查询数据库(在循环中),我会看到一条一条写入数据库的各个记录。我的期望是只有在方法完成后才应该编写它们。感谢您对@Rollback 的见解,因为在我第一次更正这个其他问题后知道它会很有用。
    • 然后删除TransactionalRollback 并使用TestTransaction 抽象手动管理事务。您可以使用startendflagForCommit 方法。
    • 抱歉,现在我很困惑。因此,如果我正确阅读了此评论,我将无法测试我打算使用的代码。我不能使用事务性。我必须用 TestTranaction 替换它。我希望这是在 junit 测试中使用的 Transactional 的直接替换注释,但情况似乎并非如此。我在 TestTranaction 上搜索了帮助,但没有得到任何有用的信息。如果它是完全不同的东西,那么如果我无法在我的开发环境中检查它的行为,我不知道我在部署它时如何对我的代码有信心。
    • 我想我可以将本地应用服务器连接到 oracle db 并从那里调试代码。这是我唯一可行的选择吗?
    猜你喜欢
    • 2010-11-01
    • 2020-04-13
    • 2021-12-29
    • 2015-06-28
    • 2015-09-24
    • 1970-01-01
    • 1970-01-01
    • 2022-12-03
    • 1970-01-01
    相关资源
    最近更新 更多