文档章节

Spring Transaction 事务控制

坚持不懈丶
 坚持不懈丶
发布于 2015/07/24 13:53
字数 1652
阅读 97
收藏 2

数据库事务的概念:事务可以看做是一系列操作组成的工作单元。这个工作单元是一个完整主体。工作单元中的一系列操作要么都执行成功,要么都执行失败。

事务的四个特性(ACID):

1.原子性(Atomicity):事务是不可分割的工作单元。要么都执行成功,要么都不成功

2.一致性(Consistency):事务的执行不会破坏数据库的完整性。

3.隔离性(Isolation):并发的事务之间相互之间不影响,通过事务隔离级别来指定隔离性

4.持久性(Durability):事务一旦执行完成之后,对数据库的修改是永久性的。不会被外界因素改变。

在实际的开发过程中,经常会后并发访问数据库的情况。即多个事务同时修改数据库信息。常见的问题包括:

丢失更新:当某一个事务修改了数据库的某条记录,在该事务提交前,另一个事务也对该条记录做了修改。前一个事务的修改被后面的事务修改给覆盖了。

         导致第一个事务修改的数据丢失,这是由于没有对修改记录加锁造成的。

脏读:一个事务读到了另一个事务还未提交的数据。

不可重复读:同一个事务两次查询同一条记录返回的结果不一样,由于两次查询中另一个事务对该记录修改造成的。

幻读:同一事务两次查询结果不同,由于两次查询中另以事务又插入了新的数据,两次查询出了两批记录,好像出现了幻觉一样。

上述问题的发生都是由于并发事务之间的隔离没有做好而引起的。解决这些问题就是设置合理的事务隔离级别。

事务的隔离级别包括:未提交读(read_uncommitted)、提交读(read_commit)、可重复读(repeatable_read)、序列化(serialable).

四个隔离级别的隔离性是递增的。隔离级别越高,数据库的并发能力就越差,所以在实际开发过程中需要在数据库并发能力和满足实际业务要求之间做权衡。

未提交读:最低的隔离级别,可能导致丢失更新、脏读、不可重复读、幻读。

提交读:一个事务只能读到其他事务提交之后的数据,这个是大多数数据库默认的隔离级别。可以避免丢失更新和脏读。仍有可能造成不可重复读和幻读。

可重复读:可以避免丢失更新、脏读、不可重复读。可能造成幻读。

序列化:最高的隔离级别,事务之间没有并发能力,所有事务都是串行化运行的。可以避免丢失更新、脏读、不可重复读、幻读。

Spring 提供了统一的事务管理。根据事务的配置方式不同可以分为:编程式事务和声明式事务两种。

建议使用声明式事务,其中声明式事务又分为两种:一种是使用注解@Transactional声明;另一种是使用切面的方式统一进行拦截。

注解方式相对灵活,切面方式比较依赖前期的约定和配置。由于前期的项目约定并不完整,我们项目中采用了注解的方式进行事务的控制。

Spring使用@Transaction来指定事务属性,可以在接口、类或方法上指定,如果类和方法上都指定了
@Transaction ,则方法上的事务属性被优先使用,具体属性如下:
• value:指定事务管理器名字,默认使用<tx:annotation-driven/>指定的事务管理器,用于支持多事务管理器环境;
• propagation:指定事务传播行为,默认为Required,使用Propagation.REQUIRED指定;
• isolation:指定事务隔离级别,默认为“DEFAULT”,使用Isolation.DEFAULT指定;
• readOnly:指定事务是否只读,默认false表示事务非只读;
• timeout:指定事务超时时间,以秒为单位,默认-1表示事务超时将依赖于底层事务系统;
• rollbackFor:指定一组异常类,遇到该类异常将回滚事务;
• rollbackForClassname:指定一组异常类名字,其含义与<tx:method>中的rollback-for属性语义完全一样;
• noRollbackFor:指定一组异常类,即使遇到该类异常也将提交事务,即不回滚事务;
• noRollbackForClassname:指定一组异常类名字,其含义与<tx:method>中的no-rollback-for属性语义完全一样;

下面介绍一下propagation和isolation属性对应的值的含义:

1.propagation对应的值是一个枚举包含以下几个值:

     REQUIRED:这是propagation的默认值,如果当前存在事务则加入事务,如果不存在事务则创建一个事务。

SUPPORTS:如果当前存在事务则加入事务,如果不存在就已无事务的方式运行。
MANDATORY:强制必须当前有事务存在,如果不存在事务则抛出异常。
REQUIRES_NEW:不管当前有没有事务,都创建一个新的事务。
NOT_SUPPORTED:如果当前存在事务,那么停止使用事务。
NEVER:强制不使用事务,如果当前存在事务则抛出异常
NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中,如果没有活动的事务,则按照REQUIRED属性执行,它使用一个单独的事务。
        这个事务拥有多个回滚的保存点,内部事务的回滚不会对外部事务造成影响,它只对DataSource TransactionManager事务管理器起效。

2.isolation对应的值也是一个枚举包含以下几个值(对应前面讲到的开发常见问题解决方案):

     DEFAULT:默认的隔离级别

READ_UNCOMMITTED:未提交读

READ_COMMITTED:提交读

REPEATABLE_READ:可重复读

SERIALIZABLE:序列化

Spring官方文档上的描述是这样的:

You can place the @Transactional annotation before an interface definition, a method on an Interface a class definition, or a public method on a class

但是建议只在实现类和实现类的方法上进行注解的使用。因为如果使用CGLIB的方式代理机制接口上的@Transactional是不会被实现类集成下来的,可能会造成配置事务无法使用的问题。先写到这如有疑问欢迎前来探讨!


© 著作权归作者所有

共有 人打赏支持
坚持不懈丶
粉丝 2
博文 16
码字总数 13904
作品 0
杭州
程序员
私信 提问
springmvc学习笔记(8)-springmvc整合mybatis之service

springmvc学习笔记(8)-springmvc整合mybatis之service 标签: springmvc mybatis [TOC] 本文记录如何整合service,包括定义spring接口,在spring容器配置service以及事务控制。让spring管理s...

brianway
2016/03/11
183
0
Spring Transaction + MyBatis SqlSession事务管理机制研究学习

原文地址:Spring Transaction + MyBatis SqlSession事务管理机制研究学习 线上的系统中,使用的是Spring+Mybatis+Mysql搭建的框架,由于客户需要,最近一直在对性能提升部分进行考虑,主要是...

Realfighter
2015/01/10
0
1
Spring的事务管理难点剖析(3):事务方法嵌套调用的迷茫

Spring事务传播机制回顾 Spring事务一个被讹传很广说法是:一个事务方法不应该调用另一个事务方法,否则将产生两个事务。结果造成开发人员在设计事务方法时束手束脚,生怕一不小心就踩到地雷...

icheer
2012/07/17
0
0
jfinal 如何使用spring事物管理?

applicationContext.xml配置 spring注解事物已经开启、 ActiveRecordPlugin数据源也是spring bean获取的,service也是spring注入的 为什么在service使用@Transactional注解不回滚?...

hybridtheorylink
2017/03/21
99
0
Spring的事务管理难点剖析(5):联合军种作战的混乱

Spring抽象的DAO体系兼容多种数据访问技术,它们各有特色,各有千秋。像Hibernate是非常优秀的ORM实现方案,但对底层SQL的控制不 太方便;而iBatis则通过模板化技术让你方便地控制SQL,但没有...

icheer
2012/07/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

想问一下C++里queue要怎么遍历

如题,想知道怎么遍历<queue>对象的元素? 貌似不能遍历。要么全部pop push一遍,要么换个容器呗。 queue是先进后出的数据类型,只能不断读top()然后再pop()掉。故意把遍历操作隐藏掉了,...

shzwork
昨天
2
0
Ubuntu 18.04.2 LTS nvidia-docker2 : 依赖: docker-ce (= 5:18.09.0~3-0~ubuntu-bionic)

平台:Ubuntu 18.04.2 LTS nvidia-docker2 版本:2.0.3 错误描述:在安装nvidia-docker2的时候报dpkg依赖错误 nvidia-docker2 : 依赖: docker-ce (= 5:18.09.0~3-0~ubuntu-bionic) 先看一下依......

Pulsar-V
昨天
2
0
学习笔记1-goland结构体(struct)

写在前面:若有侵权,请发邮件by.su@qq.com告知。 转载者告知:如果本文被转载,但凡涉及到侵权相关事宜,转载者需负责。请知悉! 本文永久更新地址:https://my.oschina.net/bysu/blog/3036...

不最醉不龟归
昨天
4
0
【转】go get命令使用socket代理

由于某些不可描述的原因,国内使用go get命令安装某些包的时候会超时导致失败,比如net包、sys包、tools包等。第一种解决办法就是自己从git上下载后添加链接到GOPATH中,比如: 1234...

yiduwangkai
昨天
6
0
从上往下打印出二叉树的每个节点,同层节点从左至右打印。

//第一种做法 public class Solution { public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) { ArrayList <Integer> li=new ArrayList<Integer>(); ArrayList <TreeN......

南桥北木
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部