我们先来理解一下什么是事务概念
事务(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,开启事务注解
在测试一次