大家都知道,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. UVA.10130 SuperSale (DP 01背包)

    UVA.10130 SuperSale (DP 01背包) 题意分析 现在有一家人去超市购物.每个人都有所能携带的重量上限.超市中的每个商品有其相应的价值和重量,并且有规定,每人每种商品最多购买一个. ...

  2. HDOJ.2955 Robberies (01背包+概率问题)

    Robberies 算法学习-–动态规划初探 题意分析 有一个小偷去抢劫银行,给出来银行的个数n,和一个概率p为能够逃跑的临界概率,接下来有n行分别是这个银行所有拥有的钱数mi和抢劫后被抓的概率pi, ...

  3. bzoj1297: [SCOI2009]迷路(矩阵乘法+拆点)

    题目大意:有向图里10个点,点与点之间距离不超过9,问从1刚好走过T距离到达n的方案数. 当时看到这题就想到了某道奶牛题(戳我).这两道题的区别就是奶牛题问的是走T条边,这道题是每条边都有一个边权求走 ...

  4. 【DP】【P2224】】【HNOI2001】产品加工

    传送门 Description 某加工厂有\(A\).\(B\)两台机器,来加工的产品可以由其中任何一台机器完成,或者两台机器共同完成.由于受到机器性能和产品特性的限制,不同的机器加工同一产品所需的时 ...

  5. pexpect正确的打开方式

    今天在写一个Python脚本时遇到一个问题——同样的代码,在Python终端执行没问题,在脚本里执行却不行,就是下面这段代码: import pexpect password = 'test2014' ...

  6. Codeforces Round #331 (Div. 2) B. Wilbur and Array

    B. Wilbur and Array time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  7. js的数据类型--字符串

    js的数据类型——字符串 这篇我们来说说js的第二种数据类型——字符串. js的内置功能之一就是字符串拼接.如果将加号(+)运算符用于数字,表示两数相加.但将它作用于字符串,则表示字符串拼接,将第二个 ...

  8. 使用 html2canvas 实现浏览器截图

    基于上一篇<h5 本地上传图片预览 源码下载>,今天分享一个图片上传后, 根据所上传的图片颜值随机生成一个答案, 并且可以生成一张专属于自己的名片. 首先上传预览我们已经实现了, 所以接下 ...

  9. HDU 5643 King's Game | 约瑟夫环变形

    经典约瑟夫环 }; ; i<=n; i++) { f[i] = (f[i-] + k) % i; } 变形:k是变化的 #include <iostream> #include &l ...

  10. 51Nod 1082 | 模拟

    Input示例 5 4 5 6 7 8 Output示例 30 55 91 91 155 模拟 #include "bits/stdc++.h" using namespace s ...