交易测试不会在完成后回滚
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))");
你能告诉我是什么阻止了测试完成后回滚吗?
您可以尝试以下方法:
- 使用
添加新的应用配置文件
spring.profile.active=test,DEV..ETC
- 在测试配置文件中,使用新的数据库凭据进行测试并使用以下休眠 属性
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;
我正在使用 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))");
你能告诉我是什么阻止了测试完成后回滚吗?
您可以尝试以下方法:
- 使用 添加新的应用配置文件
spring.profile.active=test,DEV..ETC
- 在测试配置文件中,使用新的数据库凭据进行测试并使用以下休眠 属性
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;