🔎事务的定义
将一组操作封装成一个执行单元, 即这一组操作一同成功 / 一同失败
举个栗子🌰
未使用事务
滑稽老哥给女神转账 520
由于某种原因, 女神并未收到转账的 520, 而滑稽老哥却被扣款 520
使用事务
滑稽老哥给女神转账 520
由于某种原因, 女神并未收到转账的 520
因为使用事务, 所以滑稽老哥的钱也被重新打回账户上
(一同成功 / 一同失败)
🔎Spring—事务的实现
Spring—事务的实现有 2 种方式
- 通过代码的方式手动实现事务(即 Spring 编程式事务)
- 通过注解的方式实现事务(即 Spring 声明式事务)
铺垫
后续内容针对数据表 userinfo 进行演示🍂
-- 创建用户表 drop table if exists userinfo; create table userinfo( id int primary key auto_increment, username varchar(100) not null, password varchar(32) not null, photo varchar(500) default '', createtime timestamp default current_timestamp, updatetime timestamp default current_timestamp, `state` int default 1 ) default charset 'utf8mb4'; -- 添加一个用户信息 INSERT INTO `excnblog`.`userinfo` (`id`, `username`, `password`, `photo`, `createtime`, `updatetime`, `state`) VALUES (1, 'admin', 'admin', '', '2021-12-06 17:10:48', '2021-12-06 17:10:48', 1);
Controller 层(UserController) → Service 层(UserService) → Mapper 层(UserMapper)🍂
UserController
代码在 Spring 编程式事务
UserService
@Service public class UserService { @Autowired private UserMapper userMapper; public Integer add(UserInfo userInfo) { return userMapper.add(userInfo); } }
UserMapper
@Mapper public interface UserMapper { int add(UserInfo userInfo); }
UserMapper 对应的 SQL 语句
<insert id="add"> insert into userinfo(username, password) values(#{username}, #{password}) </insert>
UserInfo
@Data public class UserInfo { private Integer id; private String username; private String password; private String photo; private String createtime; private String updatetime; private Integer state; }
Spring 编程式事务
Spring 编程式事务与 MySQL 操作事务类似, 分为 3 个部分
- 开启事务
- 提交事务
- 回滚事务
@RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @Autowired private DataSourceTransactionManager transactionManager; @Autowired private TransactionDefinition transactionDefinition; @RequestMapping("/add") public Integer add(UserInfo userInfo) { // 非空校验 if(userInfo == null || !StringUtils.hasLength(userInfo.getUsername()) || !StringUtils.hasLength(userInfo.getPassword())) { return 0; } // 1. 开启事务 TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition); // 执行相关业务代码 int ret = userService.add(userInfo); System.out.println("add : " + ret); // 2. 提交事务 transactionManager.commit(transactionStatus); // 3. 回滚事务 transactionManager.rollback(transactionStatus); return ret; } }
验证效果(开启事务 + 提交事务)🍂
验证效果(开启事务 + 回滚事务)🍂
Spring 声明式事务
利用注解 @Transactional 实现 Spring 声明式事务
@Transactional 的特点
- 可以添加在类 / 方法上(默认情况下 @Transactional 针对的是 public 修饰的方法)
- 方法执行前自动开启事务, 方法执行期间出现异常 → 自动回滚事务, 方法执行完(无异常) → 自动提交事务
举个栗子🌰
方法执行期间出现异常 → 自动回滚事务
方法执行完(无异常) → 自动提交事务
@Transactional 的参数
| 参数 | 作用 |
| value | 配置多个事务管理器时, 可指定需要的事务管理器 |
| transactionManager | 配置多个事务管理器时, 可指定需要的事务管理器 |
| propagation | 事务的传播行为, 默认值为 Propagation.REQUIRED |
| isolation | 事务的隔离级别, 默认值为 Isolation.DEFAULT |
| timeout | 事务的超时时间, 默认值为 -1, 表示超时时间为无限大, 即事务将一直持续直到完成或手动回滚(如果超出设置的时间限制事务仍未完成, 则自动回滚事务) |
| readOnly | 指定事务是否为只读, 默认值为 false(为了忽略不需要事务的方法, 例如读取数据, 设置 read-only 为 true) |
| rollbackFor | 用于指定能够触发事务回滚的异常类型(可指定多个异常类型) |
| rollbackForClassName | 用于指定能够触发事务回滚的异常类型(可指定多个异常类型) |
| noRollbackFor | 抛出指定的异常类型, 不回滚事务(可指定多个异常类型) |
| noRollbackForClassName | 抛出指定的异常类型, 不回滚事务(可指定多个异常类型) |








