Spring事务和事务传播机制
- 1. 事务回顾
- 1.1 什么是事务?
- 1.2 为什么需要事务?
- 1.3 事务的操作
- 2. Spring 中事务的实现
- 2.1 Spring编程式事务(了解)
- 2.2 Spring声明式事务@Transactional
- 3. @Transactional 详解
- 3.1 rollbackFor
- 3.2 事务隔离级别
- 3.2.1 MySQL事务隔离级别(回顾)
- 3.2.2 Spring 事务隔离级别
- 3.3 Spring 事务传播机制
- 3.3.1 什么是事务传播机制
- 3.3.2 事务的传播机制有哪些
1. 事务回顾
1.1 什么是事务?
事务是⼀组操作的集合,是⼀个不可分割的操作.
事务会把所有的操作作为⼀个整体,⼀起向数据库提交或者是撤销操作请求.所以这组操作要么同时成功,要么同时失败.
1.2 为什么需要事务?
1.3 事务的操作
事务的操作主要有三步:
- 开启事starttransaction/begin(⼀组操作前开启事务)
- 提交事务:commit(这组操作全部成功,提交事务)
- 回滚事务:rollback(这组操作中间任何⼀个操作出现异常,回滚事务)
2. Spring 中事务的实现
Spring 中的事务操作分为两类:
- 编程式事务(⼿动写代码操作事务).
- 声明式事务(利⽤注解⾃动开启和提交事务).
在学习事务之前,我们先准备数据和数据的访问代码
需求: ⽤⼾注册,注册时在⽇志表中插⼊⼀条操作记录.
数据准备:
-- 创建数据库DROP DATABASE IF EXISTS trans_test;CREATE DATABASE trans_test DEFAULT CHARACTER SET utf8mb4;use trans_test;-- 用户表DROP TABLE IF EXISTS user_info;CREATE TABLE user_info (`id` INT NOT NULL AUTO_INCREMENT,
`user_name` VARCHAR (128) NOT NULL,`password` VARCHAR (128) NOT NULL,`create_time` DATETIME DEFAULT now(),`update_time` DATETIME DEFAULT now() ON UPDATE now(),PRIMARY KEY (`id`)) ENGINE = INNODB DEFAULT CHARACTER
SET = utf8mb4 COMMENT = '用户表';
-- 操作日志表DROP TABLE IF EXISTS log_info;CREATE TABLE log_info (`id` INT PRIMARY KEY auto_increment,`user_name` VARCHAR ( 128 ) NOT NULL,`op` VARCHAR ( 256 ) NOT NULL,`create_time` DATETIME DEFAULT now(),`update_time` DATETIME DEFAULT now() ON UPDATE now()
) DEFAULT charset 'utf8mb4';
2.1 Spring编程式事务(了解)
Spring ⼿动操作事务和上⾯MySQL操作事务类似,有3个重要操作步骤:
- 开启事务(获取事务)
- 提交事务
- 回滚事务
2.2 Spring声明式事务@Transactional
声明式事务的实现很简单,只需要在需要事务的⽅法上添加@Transactional 注解就可以实现了.⽆需⼿动开启事务和提交事务,进⼊⽅法时⾃动开启事务,⽅法执⾏完会⾃动提交事务,如果中途发⽣了没有处理的异常会⾃动回滚事务.
运⾏程序,发现数据插⼊成功.
修改程序,使之出现异常
我们⼀般会在业务逻辑层当中来控制事务,因为在业务逻辑层当中,⼀个业务功能可能会包含多个数
据访问的操作.在业务逻辑层来控制事务,我们就可以将多个数据访问操作控制在⼀个事务范围内.
上述代码在Controller中书写,只是为了⽅便学习.
@Transactional 作⽤
@Transactional 可以⽤来修饰⽅法或类:
- 修饰⽅法时:只有修饰public⽅法时才⽣效(修饰其他⽅法时不会报错,也不⽣效)[推荐]
- 修饰类时:对@Transactional 修饰的类中所有的public⽅法都⽣效.
⽅法/类被@Transactional 注解修饰时,在⽬标⽅法执⾏开始之前,会⾃动开启事务,⽅法执⾏结束之后,⾃动提交事务.
如果在⽅法执⾏过程中,出现异常,且异常未被捕获,就进⾏事务回滚操作.
如果异常被程序捕获,⽅法就被认为是成功执⾏,依然会提交事务.
⼿动回滚事务
3. @Transactional 详解
3.1 rollbackFor
@Transactional 默认只在遇到运⾏时异常和Error时才会回滚,⾮运⾏时异常不回滚.即Exception的⼦类中,除了RuntimeException及其⼦类.
结论:
- 在Spring的事务管理中,默认只在遇到运⾏时异常RuntimeException和Error时才会回滚.
- 如果需要回滚指定类型的异常,可以通过rollbackFor属性来指定.
3.2 事务隔离级别
3.2.1 MySQL事务隔离级别(回顾)
SQL标准定义了四种隔离级别,MySQL全都⽀持.这四种隔离级别分别是:
3.2.2 Spring 事务隔离级别
3.3 Spring 事务传播机制
3.3.1 什么是事务传播机制
事务传播机制就是:多个事务⽅法存在调⽤关系时,事务是如何在这些⽅法间进⾏传播的.
⽐如有两个⽅法A,B都被@Transactional 修饰, A⽅法调⽤B⽅法A⽅法运⾏时,会开启⼀个事务.
当A调⽤B时,B⽅法本⾝也有事务,此时B⽅法运⾏时,是加⼊A的事务,还是创建⼀个新的事务呢?
这个就涉及到了事务的传播机制.
- 事务隔离级别解决的是多个事务同时调⽤⼀个数据库的问题
- ⽽事务传播机制解决的是⼀个事务在多个节点(⽅法)中传递的问题
3.3.2 事务的传播机制有哪些