【问题标题】:@Transactional doesn't rollback on DAO @Test methods@Transactional 不会回滚 DAO @Test 方法
【发布时间】:2019-01-27 16:20:52
【问题描述】:

我创建了一个 MySQL 数据库,并填充了用于测试的行。我想在这个数据库上做我的 DAO 单元测试。每个@Test 都是@Transactional,因此每次测试后都会进行回滚。不幸的是,它无法正常工作,因为我的数据库仍在进行更改。

我正在使用以下 context.xml 加载我的 Spring 配置

<beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:jdbc="http://www.springframework.org/schema/jdbc"
            xsi:schemaLocation="http://www.springframework.org/schema/beans
                                                    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                                                    http://www.springframework.org/schema/jdbc
                                                    http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd"
            xmlns:tx="http://www.springframework.org/schema/tx">

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />  
        <property name="url" value="jdbc:mysql://localhost:3306/push_test" />  
        <property name="username" value="push_dao" />  
        <property name="password" value="pushpassword" />
    </bean>

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

    <bean id="userPushDAO" class="my.package.userPushDAOImpl">
         <property name="dataSource" ref="dataSource"/>
    </bean>
</beans>

Thisstackoverflow问题说我

必须在应用程序上下文中提供PlatformTransactionManager bean

但即使有了它(在我的上下文中它是 transactionManager),什么也没有发生,我的数据库仍然被修改而不是回滚。

这是我的 DAO 测试类

public class UtilisateurPushDAOImplTest {

    private static ApplicationContext ctx;

    private static UserPushDAO userPushDAO;


    @BeforeClass
    public static void doSetup() {
        ctx = new ClassPathXmlApplicationContext("context.xml");
        userPushDAO = (userPushDAO) ctx.getBean("userPushDAO");
    }

    @Test
    @Transactional
    public void test() {
         userPushDAO.deleteById("id");
    }
}

我是否在我的配置或我的理解中遗漏了关于@Transactional 应该如何工作/做什么的内容?

【问题讨论】:

  • 我认为您根本不需要@Transactional。根据the Spring docs,“默认情况下,框架将为每个测试创建和回滚一个事务。”
  • @DaveyDaveDave 即使没有它,它仍然在修改我的数据库:/ 我想我可以把@Transactional 留在那里,这样我的代码就更容易理解了
  • @Transactional 不会每次都回滚。只有在完成事务中的所有操作出现异常时才会回滚。
  • @Devendra from Spring documentation 它说:“用 @Transactional 注释测试方法会导致测试在默认情况下在完成后自动回滚的事务中运行测试。”
  • @Transactional on tests 仅适用于 SpringRunner 作为单元测试运行器。如果您自己创建应用程序上下文,则它不起作用。

标签: java mysql spring


【解决方案1】:

正如@M.Deinum 在评论部分发布的那样,

@Transactional on tests 仅适用于 SpringRunner 作为单元测试运行器。

如果你自己创建应用上下文是行不通的。

另外不要忘记将事务架构添加到context.xml 中,以便能够正确加载您的上下文文件。

DAO 测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:/context.xml"})
public class UserPushDAOImplTest {
    
    @Resource(name="userPushDAO")
    private UserPushDAO userPushDAO;

    @Test
    @Transactional
    public void test() {
         userPushDAO.deleteById("id");
    }
}

context.xml

<beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:jdbc="http://www.springframework.org/schema/jdbc"
            xmlns:tx="http://www.springframework.org/schema/tx"
            xmlns:context="http://www.springframework.org/schema/context"
            xsi:schemaLocation="http://www.springframework.org/schema/beans
                                http://www.springframework.org/schema/beans/spring-beans.xsd
                                http://www.springframework.org/schema/jdbc
                                http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
                                http://www.springframework.org/schema/context
                                http://www.springframework.org/schema/context/spring-context.xsd">  

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />  
        <property name="url" value="jdbc:mysql://localhost:3306/push_test" />  
        <property name="username" value="push_dao" />  
        <property name="password" value="pushpassword" />
    </bean>
    
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource"  ref="dataSource" />    
    </bean>

    <bean id="userPushDAO" class="my.package.userPushDAOImpl">
        <property name="dataSource" ref="dataSource"/>
    </bean>
</beans>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-03
    • 1970-01-01
    • 2013-09-16
    • 2012-08-25
    • 2016-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多