实现原理 : 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 {
@Autowired
private S1Mapper s1Mapper;
@Autowired
private S2Service s2Service;
@Autowired
private 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)
@Override
public 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)
@Override
public 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)
@Override
public 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)
@Override
public 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)
@Override
public 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)
@Override
public 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)
@Override
public 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)
@Override
public void insert2(String data) {
s2Service.insert(data);
}
结果: 抛出异常,s1,s2表插入失败
NESTED
NESTED : 嵌套事务、内部事务回滚、不影响外部事务、spring默认不支持
模拟:
// 编程式事务
@Autowired
private TransactionDefinition transactionDefinition;
@Autowired
private 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)
@Override
public void insert2(String data) {
s2Service.insert(data);
// 回滚当前事务
TransactionStatus transaction = manager.getTransaction(transactionDefinition);
manager.rollback(transaction);
}