赞
踩
通过本篇学习,你将加深对 @Transactional 注解以及所有的属性的理解,还可以学习到 @Transactional 注解常见的失效场景。
@Transactional 注解特性如下:
@Transactional 注解的关键属性大致有九个(如图):
参数 | 意义 |
---|---|
isolation | 事务隔离级别,默认为DEFAULT |
propagation | 事务传播机制,默认为REQUIRED |
readOnly | 事务读写性,默认为false |
noRollbackFor | 一组异常类,遇到时不回滚,默认为{} |
noRollbackForClassName | 一组异常类名,遇到时不回滚,默认为{} |
rollbackFor | 一组异常类,遇到时回滚,默认为{} |
rollbackForClassName | 一组异常类名,遇到时回滚,默认为{} |
timeout | 超时时间,以秒为单位 |
value | 可选的限定描述符,指定使用的事务管理器,默认为“” |
隔离级别是指若干个并发的事务之间的隔离程度,与我们开发时候主要相关的场景包括:脏读取、重复读、幻读。
Isolation 的 Eum 类中定义了“五个”表示隔离级别的值,如下:
在这里,简单解释下什么是“脏读”,“不可重复读”,“幻读”:
最后,有必要补充一下常用数据库的默认隔离级别:
注意:mysql数据库,当且仅当引擎是InnoDB,才支持事务(MyIsam引擎不支持事务)。
所谓事务的传播机制是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。
Propagation 的 Eum 类中定义了“七个”表示隔离级别的值,如下:
默认情况下是 false(即:不指定只读性),设置为 true 的含义是: 告诉程序该方法下使用的是只读操作,如果进行其他非读操作,则会跑出异常。
从这一点设置的时间点开始(时间点a),到这个事务结束的过程中,其他事务所提交的数据,该事务将看不见!!即:查询中不会出现别人在时间点a之后提交的数据。
应用场景:
如果你一次执行单条查询语句,则没有必要启用事务的只读性支持,数据库默认支持SQL执行期间的读一致性;
如果你一次执行多条查询语句,例如统计查询,报表查询。在这种场景下,多条查询SQL必须保证整体的读一致性,否则,在前条SQL查询之后,后条SQL查询之前,数据被其他用户改变,则该次整体的统计查询将会出现读数据不一致的状态。此时,就有必要启用事务的只读性支持。
【注意】:是一次执行多次查询来统计某些信息,这时为了保证数据整体的一致性,要用只读事务。
用来指明不回滚的条件是哪些异常类或者异常类名。
用来指明回滚的条件是哪些异常类或者异常类名。
Spring默认情况下会对运行期异常(RunTimeException)进行事务回滚,如果遇到checked异常就不回滚。
用于设置事务处理的时间长度,阻止可能出现的长时间的阻塞系统或者占用系统资源,单位为秒。
如果超时设置事务回滚,并抛出TransactionTimedOutException异常。
value 主要用来指定不同的事务管理器,主要用来满足在同一个系统中,存在不同的事务管理器的场景需要。
比如,在Spring中声明了两种事务管理器txManager1,txManager2。然后,用户可以根据需要,修改这个参数来指定特定的txManager。
存在多个事务管理器的情况:在一个系统中,需要访问多个数据源,则必然会配置多个事务管理器。
@Transactional 注解的看似简单易用,但如果对它的用法一知半解,还是会踩到很多坑的。
我总结了六种常见的失效场景,概要如下,具体分析,请请看我另一篇博文:@Transactional 注解的失效场景,这个问题见过太多的人栽跟头,一篇刨根问底,让面试官都闭嘴
最后,附一张 @Transactional 注解的类源码图片,方便大家学习的时候做属性对照:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。