我们先来理解一下什么是事务概念 事务(transaction):最小的不可再分的工作单元;通常一个事务对应一个完整的业务(例如银行账户转账业务,该业务就是一个最小的工作单元)
事务只和DML语句有关,或者说只有DML语句才有事务。
在事物进行过程中,未结束之前,DML语句不会更改底层数据,它只是将历史操作记录一下,在内存中完成记录。只有在事物结束的时候,而且是成功的结束的时候,才会修改底层硬盘文件中的数据。
下面我们来通过Spring来测试一下
环境搭建
1.导入相关依赖(数据源,数据库驱动,Spring——jdbc)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>新建文件夹</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.13.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
</dependencies>
</project>
2.配置数据源
@Configuration
@ComponentScan("com.Tx")
public class TxConfig {
// 注册c3p0数据源
@Bean
public DataSource dataSource() throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser("root");
dataSource.setPassword("123456");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
return dataSource;
}
3.注册Bean
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) throws Exception {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
return jdbcTemplate;
}
?4.创建Dao
@Repository
public class UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public void insert() {
String sql = "insert into `tbl_user`(username, age) values(?, ?)";
String username = UUID.randomUUID().toString().substring(0, 5);
jdbcTemplate.update(sql, username, 19); // 增删改都来调用这个方法
}
}
?5.创建Service
@Service
public class UserService {
@Autowired
private UserDao userDao;
public void insertUser() {
userDao.insert();
System.out.println("插入完成...");
}
}
6.创建测试类
package com.Test;
import com.Tx.TxConfig;
import com.Tx.UserService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test_tx {
public static void main(String[] args) {
test1();
}
public static void test1(){
AnnotationConfigApplicationContext annotationConfigApplicationContext=new AnnotationConfigApplicationContext(TxConfig.class);
UserService userService = annotationConfigApplicationContext.getBean(UserService.class);
userService.insertUser();
annotationConfigApplicationContext.close();
}
}
7.创建数据库
CREATE TABLE `tbl_user` ( ? `id` int(11) NOT NULL AUTO_INCREMENT, ? `username` varchar(50) DEFAULT NULL, ? `age` int(2) DEFAULT NULL, ? PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ?
8.开始测试
我们现在来看看数据表
?
?成功插入数据
我们现在来模拟事务回滚
我们故意在方法下添加报错方法,来测试数据会不会回滚,并且添加@Transactional事务注解
public void insertUser() {
userDao.insert();
System.out.println("插入完成...");
int i=2/0;
}
在Config下注册事务管理器
//注册事务管理器
@Bean
public PlatformTransactionManager transactionManager() throws Exception {
return new DataSourceTransactionManager(dataSource());
}
并且在Config上添加@EnableTransactionManagement,开启事务注解
在测试一次
我们再来看看数据库
?
我们发现并没有添加成功,事务测试成功
?
|