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

Transactional test wont rollback after completion

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

执行 JDBCTemplate 在数据库中插入一条记录的测试后,这条新插入的记录保留在客户 table 中。我尝试了不同的变体(例如,将@Transactional 和@Rollback 移到一个方法中),但都是一样的。

测试代码class:

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;
        }
    }

客户 table 是使用这行代码创建的:

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

你能告诉我是什么阻止了测试完成后回滚吗?

您可以尝试以下方法:

  1. 使用
  2. 添加新的应用配置文件

spring.profile.active=test,DEV..ETC

Checkout offical Spring docs

  1. 在测试配置文件中,使用新的数据库凭据进行测试并使用以下休眠 属性

spring.jpa.hibernate.ddl-auto=create-drop

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

更新

即使你没有使用 JPA,你也可以通过 JDPCTemplate
使用 JPA 配置 如果您想保留现有数据,您仍然可以使用

spring.jpa.hibernate.ddl-auto=create

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

 @Autowired
private JdbcTemplate jdbcTemplate;

希望对您有所帮助。

通常在使用 MySQL 并且 @Rollback(或通常回滚事务)不起作用的情况下,这是因为使用了错误的 table 输入MySQL.

较新的版本使用 InnoDB storage engine by default however older versions (or using the wrong dialect for your JPA provider) will use the MyISAM 存储引擎。

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

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

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