实现原理 : Aop (TransactionInterceptor) 实现
使用spring声明式事务注意事项
同一个bean中的方法调用必须重新声明一个bean调用、否则后续方法调用的事务默认使用第一个第二个不生效
package com.cloud.person.service.impl;import com.cloud.person.dao.S1Mapper;
import com.cloud.person.service.S1Service;
import com.cloud.person.service.S2Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;/*** @author haizhuangbu* @date 2024/3/27 09:58* @mark S1ServiceImpl*/
@Service
public class S1ServiceImpl implements S1Service {@Autowiredprivate S1Mapper s1Mapper;@Autowiredprivate S2Service s2Service;@Autowiredprivate S1Service s1Service;@Override@Transactional(propagation = Propagation.REQUIRED)public void insert(String data) {s1Mapper.insert(data);// 调用s2 想要当前类的insert2事务生效必须重新注入当前bean 调用 insert2方法s1Service.insert2(data);int i = 1 / 0;}@Transactional(propagation = Propagation.REQUIRES_NEW)@Overridepublic void insert2(String data) {s2Service.insert(data);}
}
REQUIRED
REQUIRED 存在事务、就加入事务、不存在就新建事务(默认)
模拟,当前情况 s2 依赖 s1 事务
@Override@Transactional(propagation = Propagation.REQUIRED)public void insert(String data) {s1Mapper.insert(data);// 调用s2 想要当前类的insert2事务生效必须重新注入当前bean 调用 insert2方法s1Service.insert2(data);int i = 1 / 0;}@Transactional(propagation = Propagation.REQUIRED)@Overridepublic void insert2(String data) {s2Service.insert(data);}
处理结果 : s1,s2 两张表数据全部插入失败
REQUIRES_NEW
REQUIRES_NEW: 创建新事务与其他事务没有联系、成功就插入
模拟,当前情况 s2 为新事务、不依赖 s1.s1成功失败对s2 无任何影响
@Override@Transactional(propagation = Propagation.REQUIRED)public void insert(String data) {s1Mapper.insert(data);// 调用s2 想要当前类的insert2事务生效必须重新注入当前bean 调用 insert2方法s1Service.insert2(data);int i = 1 / 0;}@Transactional(propagation = Propagation.REQUIRES_NEW)@Overridepublic void insert2(String data) {s2Service.insert(data);}
处理结果: s2 插入成功、s1 插入失败
SUPPORTS
SUPPORTS : 支持当前事务、当前事务存在就加入、不存在就按照无事务执行
模拟 1 : s1 存在事务、s2 依赖 s1 事务、全部插入失败
@Override@Transactional(propagation = Propagation.REQUIRED)public void insert(String data) {s1Mapper.insert(data);// 调用s2 想要当前类的insert2事务生效必须重新注入当前bean 调用 insert2方法s1Service.insert2(data);int i = 1 / 0;}@Transactional(propagation = Propagation.SUPPORTS)@Overridepublic void insert2(String data) {s2Service.insert(data);}
结果 1:
模拟2: 模拟 s2 插入异常、s1无事务、s2 依赖 s1, s1没有事务、s2 就是无事务执行、异常不影响数据库操作、不会触发回滚
@Override
// @Transactional(propagation = Propagation.REQUIRED)public void insert(String data) {s1Mapper.insert(data);// 调用s2 想要当前类的insert2事务生效必须重新注入当前bean 调用 insert2方法s1Service.insert2(data);}@Transactional(propagation = Propagation.SUPPORTS)@Overridepublic void insert2(String data) {s2Service.insert(data);int i = 1 / 0;}
结果: 无事务执行、s1,s2全部执行成功
MANDATORY
MANDATORY : 依赖其他事务、其他事务不存在就抛出异常
模拟:
@Override
// @Transactional(propagation = Propagation.REQUIRED)public void insert(String data) {s1Mapper.insert(data);// 调用s2 想要当前类的insert2事务生效必须重新注入当前bean 调用 insert2方法s1Service.insert2(data);}@Transactional(propagation = Propagation.MANDATORY)@Overridepublic void insert2(String data) {s2Service.insert(data);
// int i = 1 / 0;}
结果: 程序直接抛出异常、s1 不存在事务、s1数据成功插入
NOT_SUPPORTED
NOT_SUPPORTED 如果存在事务、当前事务挂起、以非事务方式执行
模拟: s1 存在事务、s2 通过非事务方式执行、s2 不受s1 影响
@Override@Transactional(propagation = Propagation.REQUIRED)public void insert(String data) {s1Mapper.insert(data);// 调用s2 想要当前类的insert2事务生效必须重新注入当前bean 调用 insert2方法s1Service.insert2(data);int i = 1 / 0;}@Transactional(propagation = Propagation.NOT_SUPPORTED)@Overridepublic void insert2(String data) {s2Service.insert(data);}
结果: s1 插入失败、s2 插入成功
NEVER
NEVER : 存在事务就抛出异常、对标 MANDATORY
模拟: s1 存在事务、s2 抛出异常
@Override@Transactional(propagation = Propagation.REQUIRED)public void insert(String data) {s1Mapper.insert(data);// 调用s2 想要当前类的insert2事务生效必须重新注入当前bean 调用 insert2方法s1Service.insert2(data);// 走不到这儿、前面抛出异常int i = 1 / 0;}@Transactional(propagation = Propagation.NEVER)@Overridepublic void insert2(String data) {s2Service.insert(data);}
结果: 抛出异常,s1,s2表插入失败
NESTED
NESTED : 嵌套事务、内部事务回滚、不影响外部事务、spring默认不支持
模拟:
// 编程式事务@Autowiredprivate TransactionDefinition transactionDefinition;@Autowiredprivate PlatformTransactionManager manager;@Override@Transactional(propagation = Propagation.REQUIRED)public void insert(String data) {s1Mapper.insert(data);// 调用s2 想要当前类的insert2事务生效必须重新注入当前bean 调用 insert2方法s1Service.insert2(data);
// int i = 1 / 0;}@Transactional(propagation = Propagation.NESTED)@Overridepublic void insert2(String data) {s2Service.insert(data);// 回滚当前事务TransactionStatus transaction = manager.getTransaction(transactionDefinition);manager.rollback(transaction);}