欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 金融 > Spring事务管理

Spring事务管理

2024/11/30 8:42:50 来源:https://blog.csdn.net/2302_77758423/article/details/140566453  浏览:    关键词:Spring事务管理

目录

一、什么是事务

二、事务管理

 三、Spring事务失效的场景

四、事务传播行为


一、什么是事务

       事务是一组操作的集合,它是一个不可分割的工作单位,这些操作要么同时成功,要么同时失败。事务的操作步骤:开启事务(一组操作开始前,开启事务 start transaction/begin)、提交事务(这组操作全部成功后,提交事务 commit)、回滚事务(中间任何一个操作出现异常,回滚事务 rollback)。

        事务的特性ACID:

  • 原子性:事务是不可分割的最小操作单元,要么全部成功,要么全部失败
  • 一致性:事务完成时,必须使所有的数据都保持一致的状态。
  • 隔离性:数据库系统提供的隔离机制,保证事务在不受外部并发操作的影响的独立环境下运行
  • 持久性:事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。

二、事务管理

        删除部门,同时删除该部门下的所有。

        注解: @Transactional

        位置:业务(service)层的方法上、类上、接口上,建议加在用于增删改的方法上

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

        可以在application.yml配置文件中开启事务管理日志,这样就可以在控制看到和事务相关的日志信息了 。在YAML格式的配置文件中,缩进是非常重要的,因为它决定了层级关系。

#spring事务管理日志
logging:level:org.springframework.jdbc.support.JdbcTransactionManager: debug
@Transactional@Overridepublic void delete(Integer id) {deptMapper.delete(id);//根据部门id删除部门int i=1/0;empMapper.deleteByDeptId(id);//根据部门id删除员工}
  @Delete("delete from emp where dept_id=#{deptId}")void deleteByDeptId(Integer deptId);

 添加Spring事务管理后,由于服务端程序引发了异常,所以事务进行回滚

 三、Spring事务失效的场景

        情况一:异常捕获处理

        原因:事务通知只有在捕捉到了目标抛出的异常,才能进行后续的回滚处理,如果目标自己处理掉了异常,事务通知无法知悉,事务失效。

        解决:在catch块中添加throw new RuntimeException抛出

        情况二:抛出检查异常

        原因:Spring默认只会回滚非检查异常(RuntimeException)。

        解决:配置rollbackFor属性@Transactianal(rollbackFor=Exception.cla),rollbackFor属性用于控制出现何种异常类型。

@Transactional(rollbackFor = Exception.class)@Overridepublic void delete(Integer id) throws Exception {deptMapper.delete(id);//根据部门id删除部门
//        int i=1/0;if (true){throw new Exception("出错了");}empMapper.deleteByDeptId(id);//根据部门id删除员工}

        情况三:非public方法导致的事务失效

        原因:Spring 为方法创建代理,添加事务通知,前提条件都是该方法是public的。

        解决:改为public方法。

四、事务传播行为

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

         所谓事务的传播行为,指的就是在A方法运行的时候,首先会开启一个事务,在A方法当中又调用了B方法, B方法自身也具有事务,那么B方法在运行的时候,到底是加入到A方法的事务当中来,还是B方法在运行的时候新建一个事务?这个就涉及到了事务的传播行为。我们要想控制事务的传播行为,在@Transactional注解的后面指定一个属性propagation,通过 propagation 属性来指定传播行为。

@Service
public class DeptLogServiceImpl implements DeptLogService {@Autowiredprivate DeptLogMapper deptLogMapper;@Transactional(propagation = Propagation.REQUIRES_NEW)//事务传播行为:不论是否有事务,都新建事务@Overridepublic void insert(DeptLog deptLog) {deptLogMapper.insert(deptLog);}
}

Propagation.REQUIRES_NEW :不论是否有事务,都创建新事务 ,运行在一个独立的事务中  

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com