一、传播属性介绍
PROPAGATION_REQUIRED | 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。 |
PROPAGATION_SUPPORTS | 支持当前事务,如果当前没有事务,就以非事务方式执行。 |
PROPAGATION_MANDATORY | 使用当前的事务,如果当前没有事务,就抛出异常。 |
PROPAGATION_REQUIRES_NEW | 新建事务,如果当前存在事务,把当前事务挂起。 |
PROPAGATION_NOT_SUPPORTED | 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 |
PROPAGATION_NEVER | 以非事务方式执行,如果当前存在事务,则抛出异常。 |
PROPAGATION_NESTED | 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。 |
二、建表sql
CREATE TABLE `sys_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`operation` varchar(10) DEFAULT NULL COMMENT '操作类型',
`createTime` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `pe_user` (
`id` varchar(40) NOT NULL COMMENT 'ID',
`username` varchar(255) NOT NULL COMMENT '用户名称',
`password` varchar(255) DEFAULT NULL COMMENT '密码',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
三、代码演示
1.REQUIRED
@Service
public class UserServiceImpl {
@Resource
UserMapper userMapper;
@Autowired
SysLogServiceImpl sysLogService;
@Transactional
public void add() {
//调用 sysLogService插入日志
sysLogService.insertLog();
userMapper.insertUser("1232143243","dong","123");
Integer.parseInt("18.239563");
}
}
@Service
public class SysLogServiceImpl {
@Autowired
SysLogMapper sysLogMapper;
@Transactional(propagation = Propagation.REQUIRED)
public void insertLog(){
sysLogMapper.insertLog("add",new Date());
}
}
测试方法:
@SpringBootTest
class StudyaopApplicationTests {
@Autowired
UserServiceImpl userService;
@Test
void contextLoads() {
userService.add();
}
}
原始数据:
启动日志:
结果:
总结:add()和 insertLog()在同一个事务,当前事务就是add()上的事务,因为add上有事务,所以insertLog()用的就是add事务,当add抛异常,insertLog()同样回滚。
2.SUPPORTS
public void add() {
sysLogService.insertLog();
userMapper.insertUser("1232143243","dong","123");
Integer.parseInt("18.239563");
}
@Transactional(propagation = Propagation.SUPPORTS)
public void insertLog(){
sysLogMapper.insertLog("add",new Date());
}
原始数据:用Propagation.REQUIRED 中
启动日志:
结果:
总结:add()上没有事务,insertLog()也就没有事务,所以即使add即使抛异常,insertLog和add也都不会回滚。
3.MANDATORY
public void add() {
sysLogService.insertLog();
userMapper.insertUser("12321432431","dong","123");
Integer.parseInt("18.239563");
}
@Transactional(propagation = Propagation.MANDATORY)
public void insertLog(){
sysLogMapper.insertLog("add",new Date());
}
初始数据:用SUPPORTS的数据
启动日志:
结果:
总结:add()上没有事务,insertLog()也就没有事务,所以insertLog会抛出异常,程序直接结束,所以没有数据插入。
4.REQUIRES_NEW
@Transactional
public void add() {
sysLogService.insertLog();
userMapper.insertUser("12321432431","dong","123");
Integer.parseInt("18.239563");
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void insertLog(){
sysLogMapper.insertLog("add",new Date());
}
初始数据:MANDATORY的结果数据
启动日志:
结果:
总结:add()上有事务,抛异常事务回滚,insertLog()此时和add不是一个事务,所以数据插入成功。
5.NOT_SUPPORTED
@Transactional
public void add() {
sysLogService.insertLog();
userMapper.insertUser("12321432431","dong","123");
//Integer.parseInt("18.239563");
}
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void insertLog(){
sysLogMapper.insertLog("add",new Date());
int ss = 1 / 0;
}
初始数据:REQUIRES_NEW结果
启动日志:
结果:
总结:add()上有事务,insertLog()抛异常事务回滚,所以没有插入,insertLog此时没有事务,计时报错,也不会回滚。
6.NEVER
@Transactional
public void add() {
sysLogService.insertLog();
userMapper.insertUser("12321432431","dong","123");
//Integer.parseInt("18.239563");
}
@Transactional(propagation = Propagation.NEVER)
public void insertLog(){
sysLogMapper.insertLog("add",new Date());
//int ss = 1 / 0;
}
初始数据:NOT_SUPPORTED数据
启动日志:
结果:
总结:add()上有事务,insertLog()抛异常事务回滚,所以没有插入,insertLog此时抛出异常,计时报错,事务回滚。
7.1 当前无事务 NESTED
public void add() {
sysLogService.insertLog();
userMapper.insertUser("12321432431","dong","123");
Integer.parseInt("18.239563");
}
@Transactional(propagation = Propagation.NESTED)
public void insertLog(){
sysLogMapper.insertLog("add",new Date());
//int ss = 1 / 0;
}
初始数据:NEVER结果数据
启动日志:
结果:
总结:add()上没有事务,insertLog()新建事务,add异常不回滚,insertLog也插入正常。
7.2 当前有事务
@Transactional
public void add() {
sysLogService.insertLog();
userMapper.insertUser("12321432432","dong","123");
Integer.parseInt("18.239563");
}
@Transactional(propagation = Propagation.NESTED)
public void insertLog(){
sysLogMapper.insertLog("add",new Date());
//int ss = 1 / 0;
}
初始数据:7.1结果
启动日志:
结果:
总结:add()上有事务,insertLog()用add事务,add异常回滚,insertLog也回滚。