目录
🍃前言
🌴事务简介
🚩 什么是事务?
🚩为什么需要事务?
🚩事务的操作
🍀Spring 中事务的实现
🚩Spring 编程式事务
🚩Spring声明式事务@Transactional
🚩@Transactional的作用
🍃前言
本篇文章主要内容为以下两个方面
- 对事务进行一个简单的介绍
- Spring中事务如何实现
🌴事务简介
事务的概念,我相信很多人在数据库的时候已经听过和了解了,所以这里只进行简单的介绍
🚩 什么是事务?
事务是⼀组操作的集合,是⼀个不可分割的操作。
事务会把所有的操作作为⼀个整体,⼀起向数据库提交或者是撤销操作请求。
所以这组操作要么同时成功,要么同时失败。
🚩为什么需要事务?
我们在进行程序开发时,也会有事务的需求.
举个例子吧
比如转账操作,A向B转账
- 第⼀步:A账⼾-100元.
- 第⼆步:B账⼾+100元.
如果没有事务,第⼀步执⾏成功了,第⼆步执⾏失败了,那么A账⼾的100元就平⽩⽆故消失了.
如果使⽤事务就可以解决这个问题,让这⼀组操作要么⼀起成功,要么⼀起失败.
🚩事务的操作
事务的操作主要有三步:
- 开启事start transaction/begin(⼀组操作前开启事务)
- 提交事务:commit(这组操作全部成功,提交事务)
- 回滚事务:rollback(这组操作中间任何⼀个操作出现异常,回滚事务)
🍀Spring 中事务的实现
前⾯课程我们讲了MySQL的事务操作,Spring对事务也进⾏了实现.
Spring 中的事务操作分为两类:
- 编程式事务(⼿动写代码操作事务).
- 声明式事务(利⽤注解⾃动开启和提交事务).
在学习事务之前,我们先准备数据和数据的访问代码
需求: ⽤⼾注册,注册时在⽇志表中插⼊⼀条操作记录
数据准备:
代码准备:
- 1. 创建项⽬spring-trans,引⼊SpringWeb,Mybatis,mysql等依赖
- 2. applicant.yml 文件配置:
- 3. model(实体类)
- 4. controller
- 5. service
- 6. model
- 7. mapper
- 测试
🚩Spring 编程式事务
Spring ⼿动操作事务和上⾯MySQL操作事务类似,有3个重要操作步骤:
- 开启事务(获取事务)
- 提交事务
- 回滚事务
SpringBoot 内置了两个对象:
- DataSourceTransactionManager 事务管理器.用来获取事务(开启事务),提交或回滚事务的
- TransactionDefinition 是事务的属性,在获取事务的时候需要将TransactionDefinition 传递进去从而获得⼀个事务TransactionStatus
我们先来实现一个增加用户,提交事务的案例,操作代码如下:
首先查看当前表中数据:
通过Postman进行访问:
再次查看表中数据:
没有任何变化,成功进行了回滚操作。
我们再来查看事务的提交:
代码:
首先查看当前表中数据:
通过Postman进行访问:
再次查看表中数据:
可以看到当前表中并没有id为4的字段,那么可以看出成功的进行了回滚
以上代码虽然可以实现事务,但操作也很繁琐,有没有更简单的实现⽅法呢?
是有的,接下来我们来看一下声命式事务
🚩Spring声明式事务@Transactional
声明式事务的实现很简单
两步操作:
1. 添加依赖
编辑
2. 在需要事务的⽅法上添加 @Transactional 注解就可以实现了.⽆需⼿动开启事务和提交事 务,进⼊⽅法时⾃动开启事务,⽅法执⾏完会⾃动提交事务,如果中途发⽣了没有处理的异常会⾃动 回滚事务.
代码:
进行访问:
查看数据库,添加成功:
使用此注解后,我们还可以从日志中观察到committing表示事务提交成功
接下来我们修改代码,使该程序出现异常,然后再看看效果
此时,我们再进行访问时,会出现异常
数据库数据也没有进行添加
观察日志,也没有出现committing,说明事务进行了回滚
小结:若加了 @Transactional注解,出现异常会自动的把数据进行回滚;若没有加@Transactional注解,数据会执行成功,不会进行回滚(事务没有开启),在表中显示。
🚩@Transactional的作用
@Transactional 可以用来修饰⽅法或类:
- 修饰⽅法时:只有修饰public⽅法时才生效(修饰其他⽅法时不会报错,也不生效)[推荐]
- 修饰类时:对 @Transactional 修饰的类中所有的public⽅法都⽣效
方法/类被 @Transactional 注解修饰时,在目标方法执行开始之前,会自动开启事务,方法执行结束之后,自动提交事务.
- 如果在方法执行过程中,出现异常,且异常未被捕获,就进行事务回滚操作.
- 如果异常被程序捕获,⽅法就被认为是成功执行,依然会提交事务.
比如我们对上述代码进行修改,对异常进行捕获
发送请求后,再次访问查看数据库,发现数据添加成功
观察日志:这些报红的信息是e.printStackTrace打印的
运⾏程序,发现虽然程序出错了,但是由于异常被捕获了,所以事务依然得到了提交.
如果想进行回滚,那么有两种方式可以实现
- 1. 重新抛出异常
- 2. 设置手动回滚