交易测试在完成后不会回滚

时间:2018-04-05 08:40:28

标签: mysql spring unit-testing spring-boot transactional

我正在使用Spring Boot 2和JUnit4以及MySQL 5.7。

执行JDBCTemplate在数据库中插入记录的测试后,这个新插入的记录仍保留在customers表中。我尝试了不同的变体(例如,将@Transactional和@Rollback移动到一个方法),但它完全相同。

测试类的代码:

import static org.junit.Assert.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Transactional;


@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {TestConfig.class})
@Transactional
@Rollback
public class TestJDBCTemplate
    {

    @Autowired
    PlatformTransactionManager transactionManager;

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Autowired
    ApplicationContext applicationContext;


    @Test
    public void testInsert()
        {
        jdbcTemplate.execute("INSERT INTO customers (first_name, last_name) VALUES (\"Jeff\", \"Johnson\")");

        // This condition is irrelevant
        assertEquals(1, 1);
        }

    }

ContextCOnfiguration的代码:     包com.example.demo.test;

import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.PlatformTransactionManager;

@Configuration
public class TestConfig
    {

    @Bean
    DataSource dataSource()
        {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();

        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/thdb");
        dataSource.setUsername("root");
        dataSource.setPassword("root");

        return dataSource;
        }

    @Bean
    PlatformTransactionManager transactionManager()
        {
        return new DataSourceTransactionManager(dataSource());
        }

    @Bean
    JdbcTemplate jdbcTemplate(DataSource dataSource)
        {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

        return jdbcTemplate;
        }
    }

使用以下代码行创建了Customers表:

jdbcTemplate.execute("CREATE TABLE customers(" + "id SERIAL, first_name VARCHAR(255), last_name VARCHAR(255))");

请告诉我在测试完成后阻止回滚的原因是什么?

2 个答案:

答案 0 :(得分:1)

您可以尝试以下操作:

  1. 使用
  2. 添加新的applciation个人资料
      

    spring.profile.active =测试,DEV..ETC

    Checkout offical Spring docs

    1. 在测试配置文件中,使用新的db凭据进行测试并使用以下hibernate属性
    2.   

      spring.jpa.hibernate.ddl-自动= 创建降

      这将生成为您创建表格,完成后,它将删除表格。

      <强>更新

      即使您没有使用JPA,也可以将JPA配置与 JDPCTemplate 一起使用 如果要保留现有数据,仍可以使用

        

      spring.jpa.hibernate.ddl-自动= 创建

      即使使用JPA,应用程序属性中的数据源配置也允许您使用jdpc模板 就像下面的

       @Autowired
      private JdbcTemplate jdbcTemplate;
      

      我希望这会有所帮助。

答案 1 :(得分:1)

通常在使用MySQL时,@Rollback(或一般回滚事务)不起作用的事实是因为在MySQL中使用了错误的表类型。

默认情况下,较新版本使用InnoDB存储引擎,但旧版本(或使用JPA提供程序的错误方言)将使用MyISAM存储引擎。

InnoDB引擎支持交易,而MyISAM类型则不支持。因此,在基于MyISAM的表上进行回滚不会做任何事情。

要修复将MySQL中的默认存储引擎设置为InnoDB,或者在创建表时指定要使用的存储引擎。

CREATE TABLE customers(
  id SERIAL, 
  first_name VARCHAR(255), 
  last_name VARCHAR(255))
ENGINE = InnoDB;