Spring对数据库的事务管理

一、事务的定义

事务是指数据库中的一个操作序列,它由一系列的 SQL指令组成

二、事务的四种特性:ACID

事务具备ACID四种特性,ACID 是Atomic (原子性)、Consistency (一-致性)、Isolation (隔离性)和Durability (持久性)的英文缩写。

1、原子性(Atomicity)

事务最基本的操作单元要么全部成功,要么全部失败,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚到事务开始前的状态,就像这个事务从来没有执行过一样。

2、一致性 (Consistency)

事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于有效状态。如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。

3、隔离性 (Isolation)

指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。

4、持久性(Durability)

指的是只要事务成功结束,它对数据库所做的更新就必须永久保存下来。即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。

三、Spring对事务的管理

对于事务管理,Spring 采用的方式是通过在高层次建立事务抽象,然后在此基础上提供一个统一的编程模型, 这意味着,Spring 具有在多种环境中配置和使用事务的能力,无论是Spring JDBC,还是以MyBatis为代表的ORM框架,Spring都能够使用统一的编程模型对事务进行管理并为事务管理提供通用的支持。
基于Spring IOC和Spring AOP,Spring 提供了声明式事务管理的方式,它允许开发人员直接在Spring容器中定义事务的边界和属性,除此之外,Spring 还实现了事务管理和数据访问的分离,在这种条件下,开发人员只需关注对当前事务的界定,其余工作将由Spring框架自动完成。

四、事务的五种隔离级别

事务的隔离级别是指若干个并发的事务之间的隔离程度。

在一个典型的应用程序中,多个事务同时运行,经常会为了完成他们的工作而操作同一个数据。并发虽然是必需的,但是会导致以下问题:

1、脏读(Dirtyread) :

脏读发生在一个事务读取了被另一个事务改写但尚未提交的数据时。如果这些改变在稍后被回滚了,那么第一个事务读取的数据就会是无效的。

2、不可重复读(Nonrepeatable read) :

不可重复读发生在一个事务执行相同的查询两次或两次以上,但每次查询的值都不相同。这通常是由于另一个并发事务在两次查询之间更新或删除数据。(对单条记录进行的操作)

3、幻读(Phantom reads) :

一个事务读取几行记录后,另一个并发事务插入了一些记录时,幻读就发生了。在后来的查询中,第一个事务就会发现一些原来没有的额外记录。(幻读是对多条记录进行的操作)

事务的隔离级别:

事务的隔离级别

1、 ISOLATION READ UNCOMMITTED 读未提交

允许读取尚未提交的更改。可能导致脏读、幻影读或不可重复读。该级别下如果一个事务已经开始写数据,则另外一个事务则不允许同时进行写操作,但允许其他事务读此行数据。

2、 ISOLATION READ COMMITTED 读已提交

允许从已经提交的并发事务读取。可防止脏读,但幻影读和不可重复读仍可能会发生,该级别应用较多。该级别下读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。

3、ISOLATION REPEATABLE READ 可重复读

对相同字段的多次读取的结果是一致的, 除非数据被当前事务本身改变。可防止脏读和不可重复读,但幻影读仍可能发生。其效果相当于对要读取的数据行保存了备份,每次从备份中读取数据。

五、事务的七种传播行为

事务传播行为
以某一个事务传播行为修饰的方法A (类)被嵌套进另一个方法B (类)的例
子说明各事务传播行为。

1、PROPAGATION REQUIRED

默认值,如果当前存在事务,则直接调用方法执行,如果当前没有事务,则创建一个新的事务,再执行方法

场景一,当A有此事务,B没有事务:
在A执行之前创建一个事务, 当A执行成功,则提交事务,因此就算B中抛出异常,也不会导致A的回滚,因为A的事务已经提交。

场景二,A有此事务,B也有此事务:
则执行A时,A会加入B的事务中,所以A或者B抛出异常,会导致整个事务的回滚,需要注意的是如果A抛出异常,B对A的异常做了处理,B也会进行回滚,因为A在事务中,事务在A方法中已经感知到异常,所以整个事务都会回滚。

代码举例说明:
User1ServiceImpl类:
1
User2ServiceImpl类:
2
分别以不同情况举例说明:

第一种:
1
第二种:
2
第三种:
3
第四种:
4
第五种:
5

2、PROPAGATION REQUIRED NEW

方法执行需要创建一个新的事务,如果当前已存在事务,则先暂停该事务。在外围方法未开启事务的情况下REQUIRES_ NEW修饰的内部方法会新开启自己的事务,且开启的事务相互独立,互不干扰。在外围方法开启事务的情况下REQUIRES_ NEW修饰的内部方法依然会单独开启独立事务,且与外部方法事务也独立,内部方法之间、内部方法和外部方法事务均相互独立,互不干扰。若外部方法捕获内部方法抛出的异常,则外部方法并不会回滚

与上一个例子类似,此处不多做解释:
1
2
分别以不同情况举例说明:

第一种:
1
第二种:
2
第三种:
3
第四种:
4
第五种:
5

3、PROPAGATION NESTED

如果执行方法的线程没有处于事务中,那么与REQUIRED相同。如果已经处于事务中,则创建一个新事务作为当前事务的嵌套事务来运行该方法在外围方法未开启事务的情况下NESTED和REQUIRED作用相同,修饰的内部方法都会新开启自己的事务,且开启的事务相互独立,互不干扰在外围方法开启事务的情况下NESTED修饰的内部方法属于外部事务的子事务,外围主事务回滚,子事务一定回滚, 而内部子事务可以单独回滚而不影响外围主事务和其他子事务

与上一个例子类似,此处不多做解释:
1
2
分别以不同情况举例说明:

第一种:
1
第二种:
2
第三种:3
第四种:
4
第五种:
5

  • 10
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值