大家都知道,Spring的声明式事务是通过事务属性来定义的,而spring的事务属性包含了5个方面:传播行为,隔离级别,是否只读,事务超时,回滚规则;

传播行为

  传播行为,是属于事务边界相关的属性,定义了何时要创建一个事务或何时使用已有的事务。

Spring提供了7种不同的传播行为:

PROPAGATION_REQUIRED 该方法必须在事务中运行,如果当前事务不存在,则启动一个新的事务,如果当前事务存在,就在这个事务中执行,是最常见的;
PROPAGATION_MANDATORY 该方法必须在事务中进行,如果没有事务,则抛出一个异常;
PROPAGATION_NESTED 如果当前存在事务,那么该方法将会在嵌套事务内运行,嵌套事务可以独立于当前事务进行单独的提交或回滚。如果当前没有事务,则进行与PROPAGATION_REQUIRED相同的操作;
PROPAGATION_SUPPORTS 表示该方法不需要必须在事务中运行,如果当前存在事务,则运行在该事务中,如果不存在,则按非事务方式运行;
PROPAGATION_REQUIRES_NEW 表示方法必须运行在它自己的事务中。如果当前存在事务,则该事务会被挂起,会启动一个新的事务来执行方法;
PROPAGATION_NOT_SUPPORTED 表示该方法不应该运行在事务中,如果当前存在事务,则在方法运行期间,该事务会被挂起;
PROPAGATION_NEVER 表示该方法不应该运行在事务中,如果当前存在事务,则会抛出一个异常;

  如果声明了方法的传播行为为PROPAGATION_REQUIRES_NEW ,这就意味着事务边界与方法自己的边界是一样的:方法在开始执行的时候启动一个新事务并在方法返回或抛出异常时结束该事务。

隔离级别

隔离级别决定了一个事务会被其他并行的事务所能影响的程度

1. 为什么要有事务隔离级别以及能解决的问题 (why)?

  在一个多用户,用并发的系统中,为了保证数据的一致性和完整性,避免出现脏读、不可重复读、幻读等情况,引入了事务隔离机制的概念;

2. 脏读、不可重复读、幻读概念?

  脏读:一个事务读取到另一事务未提交的更新新据。当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据, 那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作也可能是不正确的;

  不可重复读:在同一事务中,多次读取同一数据返回的结果有所不同。换句话说就是,后续读取可以读到另一事务已提交的更新数据。相反,“可重复读”在同一事务中多次读取数据时,能够保证所读数据一样,也就是,后续读取不能读到另一事务已提交的更新数据。

  幻读:和不可重复读类似,但不同的是不可重复读的是update,幻读的是insert。事务T1执行一次查询,然后事务T2新插入一行记录,这行记录恰好可以满足T1所使用的查询的条件。然后T1又使用相同的查询再次对表进行检索,但是此时却看到了事务T2刚才插入的新行。这个新行就称为“幻像”,因为对T1来说这一行就像突然出现的一样。

3. 事务隔离级别?

  一般来说,分为四个隔离级别:

  a. 未提交读(Read uncommitted):读未提交数据,这是事务最低的隔离级别,在并发的事务中,它充许一个事务可以读到另一个事务未提交的更新数据(会出现脏读,不可重复读和幻读);

  b. 已提交读(Read committed):读已提交数据,保证在并发的事务中,一个事务修改的数据提交后才能被另外一个事务读取到(会出现不可重复读和幻读);

  c. 可重复读(Repeatable read):可重复读,这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻读。一般是采用“快照”的方式来实现的;

  d. 可串行化(Serializable ):事务被处理为顺序执行或者说是以串行化方式执行。这是花费最高,但也是最可靠的事务隔离级别。能有效的避免脏读、不可重复读、幻读。

4. 数据库默认的隔离级别?

  每种数据库的默认隔离级别是不同的,例如SQL Server、Oracle默认Read Commited,MySQL默认Repeatable Read。

参考自:https://gist.github.com/JagoWang/4555317#file-mysql-L27

https://tech.meituan.com/innodb-lock.html

是否只读

  如果事务只对后端的数据库进行读操作,数据库可以利用事务的只读特性来进行一些优化;通过将事务设置为只读,你就可以给数据库一个机会,让它应用它认为何时的优化措施,例如Oracle对于只读事务,不启动回滚段,不记录回滚log;

  如果你一次执行多条查询语句,例如统计查询,报表查询,在这种场景下,多条查询SQL必须保证整体的读一致性,否则,在第一条SQL查询之后,第二条SQL查询之前,数据被其他用户改变,则该次整体的统计查询将会出现读数据不一致的状态,此时,应该启用事务支持。
【注意是一次执行多次查询来统计某些信息,这时为了保证数据整体的一致性,要用只读事务】

  没有事务的时候,在执行一条sql语句看到执行前点的数据状态,保证数据一致性;

  只读事务,在执行多条sql语句看到执行前点的数据状态,保证数据一致性;

事务超时

  为了使应用程序更好的运行,事务不能运行太长的时间。因为事务可能涉及对后端数据库的锁定,所以长时间的事务会不必要的占用数据库资源。

回滚规则

  默认情况下,事务只有在遇到运行期异常时才会回滚(java.lang.RuntimeException及其子类),而在遇到检查型异常时不会回滚;不过,我们可以手动设置回滚时的异常类型;

我们可以使用@Transaction注解中的noRollbackFor和RollbackFor指定某种异常是否回滚。

@Transaction(noRollbackFor=RuntimeException.class)
@Transaction(RollbackFor=Exception.class)
这样就改变了默认的事务处理方式。  

  这就要求我们在自定义异常的时候,让自定义的异常继承自RuntimeException,这样抛出的时候才会被Spring默认的事务处理准确处理。

参考自《Spring实战》

【Spring事务的事务属性】的更多相关文章

  1. Spring 声明式事务,propagation属性列表及isolation(隔离级别)

    Spring 声明式事务,propagation属性列表 TransactionDefinition接口中定义,共有7种选项可用: PROPAGATION_REQUIRED:支持当前事务,如果当前没有 ...

  2. FlushMode属性与transaction(spring注入的事务)

    一.参见hibernate的api http://tool.oschina.net/apidocs/apidoc?api=hibernate-3.6.10 http://tool.oschina.ne ...

  3. Spring事务配置的五种方式和spring里面事务的传播属性和事务隔离级别

    转: http://blog.csdn.net/it_man/article/details/5074371 Spring事务配置的五种方式 前段时间对Spring的事务配置做了比较深入的研究,在此之 ...

  4. [Spring] Spirng中的AOP进行事务的传播属性和事务隔离级别

    通知注解 前置通知(@Before):在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常) 返回后通知(@AfterReturning):在某连接点 ...

  5. 关于Spring 事务管理传播属性的配置及作用-嵌套事务

    先了解事务的7种传播属性: PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务.这是最常见的选择. PROPAGATION_SUPPORTS -- 支持当前 ...

  6. 使用spring声明式事务,spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务。

    使用spring声明式事务,spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务.

  7. 事务的传播属性及隔离级别 Spring

    事务的传播属性(Propagation) REQUIRED ,这个是默认的属性 Support a current transaction, create a new one if none exis ...

  8. spring声明式事务管理总结

    事务配置 首先在/WEB-INF/applicationContext.xml添加以下内容: <!-- 配置事务管理器 --> <bean id="transactionM ...

  9. Spring声明式事务管理基于@Transactional注解

    概述:我们已知道Spring声明式事务管理有两种常用的方式,一种是基于tx/aop命名空间的xml配置文件,另一种则是基于@Transactional 注解.         第一种方式我已在上文为大 ...

  10. Spring学习8-Spring事务管理(注解式声明事务管理)

    步骤一.在spring配置文件中引入<tx:>命名空间 <beans xmlns="http://www.springframework.org/schema/beans& ...

随机推荐

  1. [洛谷P2463][SDOI2008]Sandy的卡片

    题目大意:有$n$个字符串,求这$n$个字符串中最长的相似公共字串,相似的定义是加上一个数后相同 题解:差分,建广义后缀自动机,然后求出每个点在多少个字符串中出现过,若在$n$个中都出现,就更新答案 ...

  2. [洛谷P3250][HNOI2016]网络

    题目大意:给定一棵树.有三种操作: $0\;u\;v\;t:$在$u$到$v$的链上进行重要度为$t$的数据传输. $1\;x:$结束第$x$个数据传输. $2\;x:$询问不经过点$x$的数据传输中 ...

  3. CF9d How many trees?

    题意:求节点数为n的,高度大于等于h的二叉树的个数. 题解: 一开始没看到二叉树的限制,,,想了好久.因为数据范围很小,所以可以考虑一些很暴力的做法. 有2种DP方式都可以过. 1,f[i][j]表示 ...

  4. BZOJ3435 & 洛谷3920 & UOJ55:[WC2014]紫荆花之恋

    https://www.lydsy.com/JudgeOnline/problem.php?id=3435 https://www.luogu.org/problemnew/show/P3920 ht ...

  5. halcon程序输出成c++程序

    halcon语法程序: dev_open_window (0, 300, -1, -1, 'black', WindowID) read_image (Die4, 'C:/Users/Public/D ...

  6. HDU 2136 素数打表+求质数因子

    Largest prime factor Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  7. unix awk手册读书笔记

    http://note.youdao.com/noteshare?id=9ac76eb63a53ac000f7814454642d2b0

  8. Leetcode 200. 岛屿的个数(扩展)

    1.题目描述 给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量.一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的.你可以假设网格的四个边均被水包围. 示例 ...

  9. HDU1540 区间合并

    Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  10. HDU1358 KMP(最短循环节)

    Period Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...