Spring 事务管理

事务

事务是一组操作的集合,它是一个不可分割的工作单位,这些操作要么同时成功,要么同时失败

操作:

  • 开启事务 (一组操作开始前,开启事务):start transaction / begin
  • 提交事务 (这组操作全部成功后,提交事务):commit
  • 回滚事务 (中间任何一个操作出现异常,回滚事务):rollback

假设删除部门后要继续删除该部门员工

@Service
public class DeptServiceImpl implements DeptService{
    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private EmpMapper empMapper;
    
    @Override
    public void delete(Integer id{
        //1.删除部门
        deptMapper.delete(id);
        
        // 假如这里出现错误,只删除了部门,没删除员工
        
        //2.根据部门id,删除部门下的员工信息
        empMapper.deleteByDetId(id);
    }
}         

如上所示,将会留下不存在部门的员工,造成了数据的不一致

Spring 事务管理

注解:@Transactional,位置:Service 层方法、类、接口上

作用:将当前方法交给 Spring 进行事务管理,方法执行前开启事务;成功执行完毕提交事务;出现异常回滚事务

上述方法

@Service
public class DeptServiceImpl implements DeptService{
    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private EmpMapper empMapper;
    
    @Transactional // 交给Spring进行事务管理
    @Override
    public void delete(Integer id{
        //1.删除部门
        deptMapper.delete(id);
        
        //2.根据部门id,删除部门下的员工信息
        empMapper.deleteByDetId(id);
    }
}

同时可以开启事务管理日志

#spring事务管理日志
logging:
  level:
    org.springframework.jdbc.support.JdbcTransactionManager: debug

事务属性 - 回滚

默认情况下,只有出现运行时异常 (RuntimeException) 才回滚异常,通过 rollbackFor 属性可以控制出现何种异常类型时,回滚事务

@Service
public class DeptServiceImpl implements DeptService{
    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private EmpMapper empMapper;
    
    // 所有异常都回滚
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(Integer id{
        //1.删除部门
        deptMapper.delete(id);
        
        //2.根据部门id,删除部门下的员工信息
        empMapper.deleteByDetId(id);
    }
}         

事务属性 - 传播行为

事务传播行为是指当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行事务

@Transactional
public void a(){
    // code
    userServices.b();
    // code
}

@Transactional
public void b(){
    // code
}

上述 a 调用了 b,b 该如何进行事务,加入 a 的事务或者单独开一个事务

可以通过属性 propagation 进行控制

属性值 描述
REQUIRED (默认值) 需要事务,有则加入,无则创建新事务
REQUIRES_NEW 需要事务,无论有无都创建新事务
SUPPORTS 支持事务,有则加入,无则在无事务状态运行
NOT_SUPPORTS 不支持事务,有事务则挂起,在无事务下运行
MANDATORY 必须有事务,否则抛出异常
NEVER 必须无事务,否则抛出异常

使用示例

@Transactional
public void a(){
    // code
    userServices.b();
    // code
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void b(){
    // code
}