在Java web学习中,碰见了该代码,主要目的是实现在异常状态下也可以实现insert日志,
@Transactional(rollbackFor = Exception.class) //spring事务管理(rollbackFor = Exception.class)所有事务异常回滚
@Override //删除部门
public void delete(Integer id) throws Exception {
try {
deptMapper.deleteById(id);
int i = 1/0;
// if(true){
// throw new Exception("出错啦....");
// }
empMapper.deleteByDeptId(id); //根据部门id来删除部门下的员工
} finally {
DeptLog deptLog = new DeptLog();
deptLog.setCreateTime(LocalDateTime.now());
deptLog.setDescription("执行了解散部门的操作,此次解散的是"+id+"号部门");
deptLogService.insert(deptLog);
}
}
在insert中
@Transactional(propagation = Propagation.REQUIRES_NEW)//(propagation = Propagation.REQUIRES_NEW)默认值REQUIRES 有事务就加入到已存在的事务 但是我们需要日志发生异常正常执行,所以用
@Override
public void insert(DeptLog deptLog) {
deptLogMapper.insert(deptLog);
}
}
主要的问题是,为什么insert中需要增加Transcational,因为不是try发生异常的话,finally是一定执行的吗,在黑马教程中,还是加了Transcational,如果不设置new则默认加入delete的事务了,既然是这样为什么还要加入Transcational增加风险
然后我在去掉Transactional的情况下执行操作,发现insert并不能执行,应该是回滚了。
查询资料发现
finally
块中的代码一定会执行,即使在try
块中发生了异常。但如果finally
块中的代码操作涉及到数据库事务,而这些操作依然是主事务的一部分,那么当主事务回滚时,这些操作也会被回滚。
为了确保日志记录操作不会被主事务的回滚影响,可以在日志记录方法中使用独立的事务。具体实现方式是使用Spring的事务传播行为 REQUIRES_NEW
,这样可以在调用日志记录方法时启动一个新的独立事务,从而确保即使主事务回滚,日志记录操作也不会被回滚。