Spring 事务隔离级别和传播行为

一、spring支持的事务声明方式

  1. 编程式事务 当系统需要明确的,细粒度的控制各个事务的边界,应选择编程式事务。

  2. 声明式事务 当系统对于事务的控制粒度较粗时,应该选择声明式事务

二、spring支持7种事务传播行为

传播行为含义
propagation_required(xml文件中为required)表示当前方法必须在一个具有事务的上下文中运行,如有客户端有事务在进行,那么被调用端将在该事务中运行,否则的话重新开启一个事务。(如果被调用端发生异常,那么调用端和被调用端事务都将回滚
propagation_supports(xml文件中为supports)表示当前方法不必需要具有一个事务上下文,但是如果有一个事务的话,它也可以在这个事务中运行
propagation_mandatory(xml文件中为mandatory)表示当前方法必须在一个事务中运行,如果没有事务,将抛出异常
propagation_nested(xml文件中为nested)表示如果当前方法正有一个事务在运行中,则该方法应该运行在一个嵌套事务中,被嵌套的事务可以独立于被封装的事务中进行提交或者回滚。如果封装事务存在,并且外层事务抛出异常回滚,那么内层事务必须回滚,反之,内层事务并不影响外层事务。如果封装事务不存在,则同propagation_required的一样
propagation_never(xml文件中为never)表示当方法务不应该在一个事务中运行,如果存在一个事务,则抛出异常
propagation_requires_new(xml文件中为requires_new)表示当前方法必须运行在它自己的事务中。一个新的事务将启动,而且如果有一个现有的事务在运行的话,则这个方法将在运行期被挂起,直到新的事务提交或者回滚才恢复执行
propagation_not_supported(xml文件中为not_supported)表示该方法不应该在一个事务中运行。如果有一个事务正在运行,它将在运行期被挂起,直到这个事务提交或者回滚才恢复执行

嵌套事务和新事务:
propagation_requires_new 和 propagation_nested是容易混淆的两个传播行为。
propagation_requires_new 启动一个新的、和外层事务无关的“内部”事务。该事务拥有自己的独立隔离级别和锁,不依赖于外部事务,独立地提交和回滚。当内部事务开始执行时,外部事务将被挂起,内务事务结束时,外部事务才继续执行。

由此可见, propagation_requires_new 和 propagation_nested 的最大区别在于:
propagation_requires_new 将创建一个全新的事务,它和外层事务没有任何关系,
而propagation_nested 将创建一个依赖于外层事务的子事务,当外层事务提交或回滚时,子事务也会连带提交和回滚。

  1. 当业务方法被设置为propagation_mandatory时,它就不能被非事务的业务方法调用。
    如将ForumService#addTopic ()设置为propagation_mandatory,如果展现层的Action直接调用addTopic()方法,将引发一个异常
    正确的情况是: addTopic()方法必须被另一个带事务的业务方法调用
    所以 propagation_mandatory的方法一般都是被其它业务方法间接调用的。
  2. 当业务方法被设置为propagation_never时,它将不能被拥有事务的其它业务方法调用。假设UserService#addCredits ()设置为propagation_never,当ForumService# addTopic()拥有一个事务时,addCredits()方法将抛出异常。所以propagation_never方法一般是被直接调用的
  3. 当方法被设置为propagation_not_supported时,外层业务方法的事务会被挂起,当内部方法运行完成后,外层方法的事务重新运行。如果外层方法没有事务,直接运行,不需要做任何其它的事

三、spring中的事务隔离级别

隔离级别含义
isolation_default使用数据库默认的事务隔离级别
isolation_read_uncommitted允许读取尚未提交的修改,可能导致脏读、幻读和不可重复读
isolation_read_committed允许从已经提交的事务读取,可防止脏读、但幻读,不可重复读仍然有可能发生
isolation_repeatable_read对相同字段的多次读取的结果是一致的,除非数据被当前事务自生修改。可防止脏读和不可重复读,但幻读仍有可能发生
isolation_serializable完全服从acid隔离原则,确保不发生脏读、不可重复读、和幻读,但执行效率最低

四、spring事务只读属性
声明式事务的第三个特性是它是否是一个只读事务。如果一个事务只对后端数据库执行读操作,那么该数据库就可能利用那个事务的只读特性,采取某些优化措施。通过把一个事务声明为只读,可以给后端数据库一个机会来应用那些它认为合适的优化措施。由于只读的优化措施是在一个事务启动时由后端数据库实施的, 因此,只有对于那些具有可能启动一个新事务的传播行为(PROPAGATION_REQUIRES_NEW、PROPAGATION_REQUIRED、 ROPAGATION_NESTED)的方法来说,将事务声明为只读才有意义。

五、spring的事务超时
为了使一个应用程序很好地执行,它的事务不能运行太长时间。因此,声明式事务的下一个特性就是它的超时。
假设事务的运行时间变得格外的长,由于事务可能涉及对后端数据库的锁定,所以长时间运行的事务会不必要地占用数据库资源。这时就可以声明一个事务在特定秒数后自动回滚,不必等它自己结束。
由于超时时钟在一个事务启动的时候开始的,因此,只有对于那些具有可能启动一个新事务的传播行为(PROPAGATION_REQUIRES_NEW、PROPAGATION_REQUIRED、ROPAGATION_NESTED)的方法来说,声明事务超时才有意义。

六、事务回滚规则
事务五边形的最后一个边是一组规则,它们定义哪些异常引起回滚,哪些不引起。在默认设置下,事务只在出现运行时异常(runtime exception)时回滚,而在出现受检查异常(checked exception)时不回滚。不过,也可以声明在出现特定受检查异常时像运行时异常一样回滚。同样,也可以声明一个事务在出现特定的异常时不回滚,即使那些异常是运行时异常。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值