做体育的网站,c2c跨境电商平台有哪些?,wordpress注入,网站筹建中案例
接下来我们就通过一个案例来演示下事务传播行为propagation属性的使用。
需求#xff1a;解散部门时需要记录操作日志
由于解散部门是一个非常重要而且非常危险的操作#xff0c;所以在业务当中要求每一次执行解散部门的操作都需要留下痕迹#xff0c;就是要记录操作…案例
接下来我们就通过一个案例来演示下事务传播行为propagation属性的使用。
需求解散部门时需要记录操作日志
由于解散部门是一个非常重要而且非常危险的操作所以在业务当中要求每一次执行解散部门的操作都需要留下痕迹就是要记录操作日志。而且还要求无论是执行成功了还是执行失败了都需要留下痕迹。
步骤 执行解散部门的业务先删除部门再删除部门下的员工前面已实现 记录解散部门的日志到日志表未实现 准备工作 创建数据库表 dept_log 日志表
create table dept_log(id int auto_increment comment 主键ID primary key,create_time datetime null comment 操作时间,description varchar(300) null comment 操作描述
)comment 部门操作日志表; 引入资料中提供的实体类DeptLog
Data
NoArgsConstructor
AllArgsConstructor
public class DeptLog {private Integer id;private LocalDateTime createTime;private String description;
} 引入资料中提供的Mapper接口DeptLogMapper
Mapper
public interface DeptLogMapper {
Insert(insert into dept_log(create_time,description) values(#{createTime},#{description}))void insert(DeptLog log);
} 引入资料中提供的业务接口DeptLogService
public interface DeptLogService {void insert(DeptLog deptLog);
} 引入资料中提供的业务实现类DeptLogServiceImpl
Service
public class DeptLogServiceImpl implements DeptLogService {
Autowiredprivate DeptLogMapper deptLogMapper;
Transactional //事务传播行为有事务就加入、没有事务就新建事务Overridepublic void insert(DeptLog deptLog) {deptLogMapper.insert(deptLog);}
}
代码实现:
业务实现类DeptServiceImpl
Slf4j
Service
//Transactional //当前业务实现类中的所有的方法都添加了spring事务管理机制
public class DeptServiceImpl implements DeptService {Autowiredprivate DeptMapper deptMapper;Autowiredprivate EmpMapper empMapper;
Autowiredprivate DeptLogService deptLogService;
//根据部门id删除部门信息及部门下的所有员工OverrideLogTransactional(rollbackFor Exception.class) public void delete(Integer id) throws Exception {try {//根据部门id删除部门信息deptMapper.deleteById(id);//模拟异常if(true){throw new Exception(出现异常了~~~);}//删除部门下的所有员工信息empMapper.deleteByDeptId(id);}finally {//不论是否有异常最终都要执行的代码记录日志DeptLog deptLog new DeptLog();deptLog.setCreateTime(LocalDateTime.now());deptLog.setDescription(执行了解散部门的操作此时解散的是id号部门);//调用其他业务类中的方法deptLogService.insert(deptLog);}}//省略其他代码...
} 测试:
重新启动SpringBoot服务测试删除3号部门后会发生什么 执行了删除3号部门操作 执行了插入部门日志操作 程序发生Exception异常 执行事务回滚删除、插入操作因为在一个事务范围内两个操作都会被回滚
然后在dept_log表中没有记录日志数据 原因分析:
接下来我们就需要来分析一下具体是什么原因导致的日志没有成功的记录。 在执行delete操作时开启了一个事务 当执行insert操作时insert设置的事务传播行是默认值REQUIRED表示有事务就加入没有则新建事务 此时delete和insert操作使用了同一个事务同一个事务中的多个操作要么同时成功要么同时失败所以当异常发生时进行事务回滚就会回滚delete和insert操作 解决方案
在DeptLogServiceImpl类中insert方法上添加Transactional(propagation Propagation.REQUIRES_NEW) Propagation.REQUIRES_NEW 不论是否有事务都创建新事务 运行在一个独立的事务中。 Service
public class DeptLogServiceImpl implements DeptLogService {
Autowiredprivate DeptLogMapper deptLogMapper;
Transactional(propagation Propagation.REQUIRES_NEW)//事务传播行为不论是否有事务都新建事务Overridepublic void insert(DeptLog deptLog) {deptLogMapper.insert(deptLog);}
} 重启SpringBoot服务再次测试删除3号部门 那此时DeptServiceImpl中的delete方法运行时会开启一个事务。 当调用 deptLogService.insert(deptLog) 时也会创建一个新的事务那此时当insert方法运行完毕之后事务就已经提交了。 即使外部的事务出现异常内部已经提交的事务也不会回滚了因为是两个独立的事务。 到此事务传播行为已演示完成事务的传播行为我们只需要掌握两个REQUIRED、REQUIRES_NEW。 REQUIRED 大部分情况下都是用该传播行为即可。 REQUIRES_NEW 当我们不希望事务之间相互影响时可以使用该传播行为。比如下订单前需要记录日志不论订单保存成功与否都需要保证日志记录能够记录成功。