概述
本文主要介绍三个点:
1.spring事务传播机制分类。
2.spring事务7种传播机制的具体是什么?
3.事务嵌套时如何处理回滚?
4.事务的隔离级别。
spring事务传播机制分类。
事务的传播特性指的是不同方法的嵌套调用过程中,事务该如何处里,是用同一个事务还是不同的事务,当出现异常的时候会回滚还是提交,两个方法之前的相关影响。
spring事务传播机制可以分为三大类:支持当前事务,不支持当前事务,嵌套事务。
spring事务7种传播机制的具体是什么?
spring事务7种传播机制具体是:Required,requires_new,nested,support,not_support,never,Mandatory
名称 | 描述 | |
REQUIRED | 支持使用当前事务,如果当前事务不存在,创建一个新事务。 | |
SUPPORTS | 支持使用当前事务,如果当前事务不存在,则不使用事务。 | |
MANDATORY | 支持使用当前事务,如果当前事务不存在,则抛出Exception | |
REQUIRES_NEW | 如果当前事务存在,把当前事务挂起,创建一个新事务。 | |
NOT_SUPPORTED | 无事务执行,如果当前事务存在,把当前事务挂起,执行完具体逻辑后,恢复原事务。 | |
NEVER | 不支持事务,如果当前有事务则抛出Exception。 | |
NESTED | 嵌套事务,如果当前事务存在,那么在嵌套新建一个事务中执行。如果当前事务不存在,则新建一个事务执行。 |
事务嵌套时如何处理回滚?
不同方法的嵌套调用过程中发生异常时,事务是如何回滚的?
在日常工作中,我们使用比较多的是required,requires_new,nested.
如果外层方法是required,内层方法是requeired,requeires_new,nested
外层方法 | 内层方法 | 执行情况 |
required | requeired | 1.如果程序正常执行,那么内层事务不会提交,在外部事务中统一进行事务提交, 2.如果内层事务,或者外层事务中出现异常情况,那么会在外层事务的处理中统一进行异常回滚 |
requeires_new | 1.如果外层方法中存在事务,内层方法在运行的时候会挂起外层事务并开启一个新的事务,如果程序正常执行,则内层方法优先事务提交,然后外层方法再提交; 2.如果内层方法中存在异常,内层事务会优先回滚,外层方法事务也会回滚, 3.如果外层方法中存在异常,那么内层事务正常正常提交,而外层方法会进行回滚操作 | |
nested | 1.如果外层方法中有事务,那么直接创建一个保存点,后续操作中如果没有异常情况, 那么会清除保存点信息,并且在外层事务中进行提交操作, 2.如果内层方法中存在异常情况,那么会回滚到保存点,外层方法事务会直接进行回滚, 3.如果外层方法中存在异常情况, 那么会内层方法会正常执行,并且执行完毕之后释放保存点,并且外层方法事务会进行回滚 |
如果外层方法是requires_new内层方法是 requeired,requeires_new,nested
外层方法 | 内层方法 | 执行情况 |
requires_new | requeired | 1.如果程序正常执行,那么内层事务不会提交,在外部事务中统一进行事务提交, 2.如果内层事务,或者外层事务中出现异常情况,那么会在外层事务的处理中统一进行异常回滚 |
requeires_new | 1.如果外层方法中存在事务,内层方法在运行的时候会挂起外层事务并开启一个新的事务,如果程序正常执行,则内层方法优先事务提交,然后外层方法再提交; 2.如果内层方法中存在异常,内层事务会优先回滚,外层方法事务也会回滚, 3.如果外层方法中存在异常,那么内层事务正常正常提交,而外层方法会进行回滚操作 | |
nested | 1.如果外层方法中有事务,那么直接创建一个保存点,如果外层方法没有事务,那么就创建一个新的事务,后续操作中如果没有异常情况,那么会清除保存点信息,并且在外层事务中进行提交操作, 2.如果内层方法中存在异常情况,那么会回滚到保存点,外层方法事务会直接进行回滚, 3.如果外层方法中存在异常情况,那么会内层方法会正常执行,并且执行完毕之后释放保存点,并且外层方法事务会进行回滚 |
如果外层方法是nested内层方法是 requeired,requeires_new,nested
外层方法 | 内层方法 | 执行情况 |
nested | requeired | 1.如果程序正常执行,那么内层事务不会提交,在外部事务中统一进行事务提交, 2.如果内层事务,或者外层事务中出现异常情况,那么会在外层事务的处理中统一进行异常回滚 |
requeires_new | 1.如果外层方法中存在事务,内层方法在运行的时候会挂起外层事务并开启一个新的事务,如果程序正常执行,则内层方法优先事务提交,然后外层方法再提交; 2.如果内层方法中存在异常,内层事务会优先回滚,外层方法事务也会回滚, 3.如果外层方法中存在异常,那么内层事务正常正常提交,而外层方法会进行回滚操作 | |
nested | 1.如果外层方法中有事务,那么直接创建一个保存点,如果外层方法没有事务,那么就创建一个新的事务,后续操作中如果没有异常情况,那么会清除保存点信息,并且在外层事务中进行提交操作, 2.如果内层方法中存在异常情况,那么会回滚到保存点,外层方法事务会直接进行回滚, 3.如果外层方法中存在异常情况,那么会内层方法会正常执行,并且执行完毕之后释放保存点,并且外层方法事务会进行回滚 |
简单的总结是:判断内外方法是否是同一个事务:
是:异常统一在外层方法处理。
不是:内层方法有可能影响到外层方法,但是外层方法是不会影响内层方法的(比如nested)
事务的隔离级别
1)读未提交
量个事务A、B, 在B事务中对数据修改未提交时A事务可以读到修改的数据,隔离级别最差,会出现脏读、幻读、不可重复读。
2)读提交
事务只能看到其他事务提交的数据,不能避免幻读、不可重复读,但可以避免脏读。
不可重复读:A在查询数据,B事务在修改数据,A查询到的数据在B提交前和提交后是不一致的。
幻读:A事务修改数据,B事务增加数据,当B事务先提交后是,A提交后发现还有数据没有改。
3)可重复读
一个事务多次查询,无论其他事务对数据如何修改,看到的数据是一样的,比如在事务A执行中三次查询一个数据,同时在B事务正在修改这个数据,无论A中查询多少第,看到的都是事务B修改之前的数据,只有当A提交或回滚事务后,才能看到B修改的数据。
可以避免不可重复读和幻读,解决不了幻读的问题。
4)序列化
所有事务顺序执行,一次只有一个事务执行,其他事务必须等待,可以避免脏读、幻读、不可重复读的问题。