Spring声明式事务@Transactional 详解,事务隔离级别和传播行为
@Transactional注解支持9个属性的设置,这里只讲解其中使用较多的三个属性:readOnly、propagation、isolation。其中propagation属性用来枚举事务的传播行为,isolation用来设置事务隔离级别,readOnly进行读写事务控制。
@Service
@Transactional(readOnly = true)
public class AppTradeRec2Service extends BaseService {
@Autowired
private AppTradeRecDao appTradeRecDao;
@Autowired
private ConsInfoDao consInfoDao; @Transactional(readOnly = false)
public void payCharge(TradeRec tradeRec) {
User usr = UserUtils.getUser();
ConsInfo cons = consInfoDao.getByUser(usr.getId());
//修改交易记录
tradeRec.setPayBefore(cons.getAccountAmt());
tradeRec.setPayAfter(cons.getAccountAmt() - tradeRec.getRcvAmt());
tradeRec.setIsPay("99");
appTradeRecDao.save(tradeRec);
//修改账户余额
cons.setAccountAmt(cons.getAccountAmt() - tradeRec.getRcvAmt());
consInfoDao.save(cons);
}
}
一、readOnly读写事务控制
readOnly=true表明所注解的方法或类只是读取数据。
readOnly=false表明所注解的方法或类是增加,删除,修改数据。
二、isolation事务隔离级别
我们在使用事务过程中,通常会发生以下三种情况:
1、脏读(dirty read):当一个事务读取另一个事务尚未提交的修改时,产生脏读。
2、不可重复读(non-repeatable read):同一查询在同一事务中多次进行,由于其他提交事务所做的修改或删除,每次返回不同的结果集,此时发生非重复读。
3、幻像读(phantom read):同一查询在同一事务中多次进行,由于其他提交事务所做的插入操作,每次返回不同的结果集,此时发生幻像读。
针对上述三种情况,Spring提供了5种事务隔离级别予以解决:
1、DEFAULT默认级别
DEFAULT为数据源(数据库)的默认隔离级别,以目前常用的MySQL为例,默认的隔离级别通常为REPEATABLE_READ。
2、READ_UNCOMMITTED未授权读取级别
这是最低的隔离级别,一个事务能读取到别的事务未提交的更新数据,很不安全,可能出现丢失更新、脏读、不可重复读、幻读。
3、READ_COMMITTED授权读取级别
以操作同一行数据为前提,读事务允许其他读事务和写事务,未提交的写事务禁止其他读事务和写事务。此隔离级别可以防止更新丢失、脏读,但不能防止不可重复读、幻读。此隔离级别可以通过“瞬间共享读锁”和“排他写锁”实现。
4、REPEATABLE_READ可重复读取级别
保证同一事务中先后执行的多次查询将返回同一结果,不受其他事务影响。以操作同一行数据为前提,读事务禁止其他写事务,但允许其他读事务,未提交的写事务禁止其他读事务和写事务。此隔离级别可以防止更新丢失、脏读、不可重复读,但不能防止幻读。
5、SERIALIZABLE序列化级别
所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰。提供严格的事务隔离,此隔离级别可以防止更新丢失、脏读、不可重复读、幻读。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed。它能够避免更新丢失、脏读,而且具有较好的并发性能。尽管它会导致不可重复读、幻读这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。
三、Propagation事务传播行为
Propagation属性用来枚举事务的传播行为。所谓事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。Spring支持7种事务传播行为,默认为REQUIRED。
1、REQUIRED
REQUIRED是常用的事务传播行为,如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。
2、SUPPORTS
SUPPORTS表示当前方法不需要事务上下文,但是如果存在当前事务的话,那么这个方法会在这个事务中运行。
3、MANDATORY
MANDATORY表示该方法必须在事务中运行,如果当前事务不存在,则会抛出一个异常。不会主动开启一个事务。
4、REQUIRES_NEW
REQUIRES_NEW表示当前方法必须运行在它自己的事务中。一个新的事务将被启动,如果存在当前事务,在该方法执行期间,当前事务会被挂起(如果一个事务已经存在,则先将这个存在的事务挂起)。如果使用JTATransactionManager的话,则需要访问TransactionManager。
5、NOT_SUPPORTED
NOT_SUPPORTED表示该方法不应该运行在事务中,如果存在当前事务,在该方法运行期间,当前事务将被挂起。如果使用JTATransactionManager的话,则需要访问TransactionManager。
6、NEVER
NEVER表示当前方法不应该运行在事务上下文中,如果当前正有一个事务在运行,则会抛出异常。
7、NESTED
NESTED表示如果当前已经存在一个事务,那么该方法将会在嵌套事务中运行。嵌套的事务可以独立于当前事务进行单独地提交或回滚。如果当前事务不存在,那么其行为与REQUIRED一样。嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。
综上所述,NESTED和REQUIRES_NEW非常相似,都是开启一个属于它自己的新事务。使用REQUIRES_NEW时,内层事务与外层事务就像两个独立的事务一样,一旦内层事务进行了提交后,外层事务不能对其进行回滚。当内部事务开始执行时, 外部事务将被挂起, 内务事务结束时, 外部事务将继续执行。两个事务互不影响,两个事务不是一个真正的嵌套事务,同时它还需要JTA事务管理器的支持。
使用NESTED时,外层事务的回滚可以引起内层事务的回滚。而内层事务的异常并不会导致外层事务的回滚,它是一个真正的嵌套事务。嵌套事务开始执行时, 它将取得一个 savepoint,如果这个嵌套事务失败, 将回滚到此savepoint。潜套事务是外部事务的一部分, 只有外部事务结束后它才会被提交。
Spring声明式事务@Transactional 详解,事务隔离级别和传播行为的更多相关文章
- 详解MySQL隔离级别
一个事务具有ACID特性,也就是(Atomicity.Consistency.Isolation.Durability,即原子性.一致性.隔离性.持久性),本文主要讲解一下其中的Isolation,也 ...
- 可能是最漂亮的Spring事务管理详解
Java面试通关手册(Java学习指南):https://github.com/Snailclimb/Java_Guide 微信阅读地址链接:可能是最漂亮的Spring事务管理详解 事务概念回顾 什么 ...
- 可能是最漂亮的Spring事务管理详解 专题
微信阅读地址链接:可能是最漂亮的Spring事务管理详解 事务概念回顾 什么是事务? 事务是逻辑上的一组操作,要么都执行,要么都不执行. 事物的特性(ACID): 原子性: 事务是最小的执行单位,不允 ...
- 最漂亮的Spring事务管理详解
SnailClimb 2018年05月21日阅读 7245 可能是最漂亮的Spring事务管理详解 Java面试通关手册(Java学习指南):github.com/Snailclimb/- 微信阅读地 ...
- 这可能是最漂亮的Spring事务管理详解
事务概念回顾 什么是事务? 事务是逻辑上的一组操作,要么都执行,要么都不执行. 事物的特性(ACID): 原子性: 事务是最小的执行单位,不允许分割.事务的原子性确保动作要么全部完成,要么完全不起作用 ...
- Spring事务管理详解
事务概念回顾 什么是事务? 事务是逻辑上的一组操作,要么都执行,要么都不执行. 事物的特性(ACID): 原子性: 事务是最小的执行单位,不允许分割.事务的原子性确保动作要么全部完成,要么完全不起作用 ...
- 【Spring】——声明式事务配置详解
项目中用到了spring的事务: @Transactional(rollbackFor = Exception.class, transactionManager = "zebraTrans ...
- Spring声明式事务管理与配置详解
转载:http://www.cnblogs.com/hellojava/archive/2012/11/21/2780694.html 1.Spring声明式事务配置的五种方式 前段时间对Spring ...
- spring 声明式事务管理详解
前言:spring框架对于事务管理提供了两种方案.一,编程式事务.二,声明式事务.本例主要剖析 声明式事务. 何为声明式事务: 通过spring的配置文件配置事务规则,或使用spring @Trans ...
随机推荐
- A - Piece of Cake Kattis - pieceofcake (数学)
题目链接: A - Piece of Cake Kattis - pieceofcake 题目大意:给你一个多边形,然后给你这个多边形的每个点的坐标,让你从这个n个点中选出k个点,问这个k个点形成的面 ...
- Ajax原生请求和java对象转成json
\黑马程序员_超全面的JavaWeb视频教程vedio\黑马程序员_超全面的JavaWeb教程-源码笔记\JavaWeb视频教程_day23-资料源码\ajax_code\day23_3 本代码中有模 ...
- v2v-VMware/VSphere中虚机离线迁移至openstack平台
先决条件 exsi到openstack的迁移,分为两种,一种是静态迁移,另一种是在线迁移. 静态迁移(offline migration)也叫做常规迁移,离线迁移.在迁移之前将虚拟机暂停,同时拷贝虚拟 ...
- Boost 序列化
原文链接: https://blog.csdn.net/qq2399431200/article/details/45621921 1. 编译器 gcc, boost 1.55 2.1第一个简单的例子 ...
- 【VMware vSphere】VMware vSphere简单了解
*什么是VMware vSphere 说VMware vSphere可能刚开始都是一脸懵逼,但是看到VMware时,首先想到的是不是VMware Workstation?也就是虚拟 ...
- 自学MVC看这里——全网最全ASP.NET MVC 教程汇总(转)
自学MVC看这里——全网最全ASP.NET MVC 教程汇总 MVC架构已深得人心,微软也不甘落后,推出了Asp.net MVC.小编特意整理博客园乃至整个网络最具价值的MVC技术原创文章,为想要 ...
- MongoVUE 使用教程
MongoVUE是一款针对MongoDB的客户端工具,现在连接数据库也叫数据模式有2种方法,一种是B/S结构的数据库,通过网页就可以访问.另外一种就是基于C/S客户端的连接方式,本次为大家分享的这一个 ...
- selenium控制浏览器
1.要把浏览器设置为全屏,否则有些元素是操作失败的,如对下图进行操作按钮是失败的,因为按钮没有显示出来 2.设置浏览器的宽.高 3.控制前进.后退(不建议使用driver.black().driver ...
- 51nod--1256 乘法逆元 (扩展欧几里得)
题目: 1256 乘法逆元 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出2个数M和N(M < N),且M与N互质,找出一个数K满足0 < ...
- CF 189A Cut Ribbon
#include<bits/stdc++.h> using namespace std; const int maxn = 4000 + 131; int n, a, b, c; int ...