Spring 事物的四种隔离级别和七大传播特性

Spring 事物的四种隔离级别和七大传播特性

事务隔离级别分为四种(级别递增):

1、Read Uncommitted(读未提交) :事务中的修改,即使没有提交,其他事务也可以看得到,会导致“脏读”、“幻读”和“不可重复读取”;

2、Read Committed (读已提交):大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”,但不能避免“幻读”和“不可重复读取”。该级别适用于大多数系统。

3、Repeatable Read(可重复读) :保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但不能避免“幻读”,但是带来了更多的性能损失。

4、Serializable (串行化):最严格的级别,事务串行执行,资源消耗最大;

注解配置时如:@Transactional(isolation = Isolation.READ_UNCOMMITTED)

可重复读(repeatable-read):在开始读取数据(事务开启)时,不再允许修改操作

mysql默认的事务隔离级别为repeatable-read(可重复读)

脏读、不可重复读和幻读的解释:

事务并发导致的这些问题。

脏读:事务A读取了事务B更新的数据,然后事务B进行回滚操作,那么事务A读取到的数据是脏数据;

不可重复读:事务A多次读取同一数据,事务B在事务A多次读取的过程中,对数据进行了更新操作,导致事务A多次读取同一数据时,结果不一致;

幻读:事务A修改一些数据,事务B在这个时候插入了一条数据,事务A修改之后发现还有一条没有修改过来,好像发生幻觉一样,这就是幻读。

不可重复读和幻读很相似,但侧重点不同,不可重复读侧重于修改幻读侧重于新增或者删除。解决不可重复读只需要锁住满足条件的行,解决幻读需要锁住表。

Spring事务的七种传播机制

1、REQUIRED(默认):支持使用当前事务,如果当前事务不存在,创建一个新事务。

2、SUPPORTS:支持使用当前事务,如果当前事务不存在,则不使用事务。

3、MANDATORY:中文翻译为强制,支持使用当前事务,如果当前事务不存在,则抛出Exception。

4、REQUIRES_NEW:创建一个新事务,如果当前事务存在,把当前事务挂起。

5、NOT_SUPPORTED:无事务执行,如果当前事务存在,把当前事务挂起。

6、NEVER:无事务执行,如果当前有事务则抛出Exception。

7、NESTED:嵌套事务,如果当前事务存在,那么在嵌套的事务中执行。如果当前事务不存在,则表现跟REQUIRED一样。嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。

注解配置时如:@Transactional(propagation=Propagation.REQUIRED)

日常开发中基本只会使用到REQUIRED(1),REQUIRES_NEW(4),NESTED(7)三种。

NESTED和REQUIRES_NEW是有区别的。NESTED传播行为会沿用当前事务的隔离级别和锁等特性,而REQUIRES_NEW则可以拥有自己独立的隔离级别和锁等特性。

使用REQUIRES_NEW时,内层事务与外层事务就像两个独立的事务一样,一旦内层事务进行了提交后,外层事务不能对其进行回滚。当内部事务开始执行时, 外部事务将被挂起, 内务事务结束时,外部事务将继续执行。两个事务互不影响,两个事务不是一个真正的嵌套事务,同时它还需要JTA事务管理器的支持。

使用NESTED时,外层事务的回滚可以引起内层事务的回滚。而内层事务的异常并不会导致外层事务的回滚,它是一个真正的嵌套事务。嵌套事务开始执行时, 它将取得一个 savepoint,如果这个嵌套事务失败, 将回滚到此savepoint。潜套事务是外部事务的一部分, 只有外部事务结束后它才会被提交。

NESTED的实现主要依赖于数据库的保存点(SAVEPOINT)技术,SAVEPOINT记录了一个保存点,可以通过ROLLBACK TO SAVEPOINT来回滚到某个保存点。如果数据库支持保存点技术时就启用保存点技术;如果不支持就会新建一个事务去执行代码,也就相当于REQUIRES_NEW。

@Transactional注解支持9个属性的设置,其中使用较多的三个属性:readOnly、propagation、isolation。其中propagation属性用来枚举事务的传播行为,isolation用来设置事务隔离级别,readOnly进行读写事务控制。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring中,传播属性和隔离级别事务中重要的概念。传播属性是指事务在不同方法之间的传播方式,而隔离级别则是指事务在多个并发操作中保持数据一致性的程度。 传播属性包括: 1. REQUIRED:如果当前存在事务,则加入该事务,如果没有则创建一个新事务。 2. SUPPORTS:如果当前存在事务,则加入该事务,如果没有事务则以非事务方式执行。 3. MANDATORY:强制要求当前存在事务,否则抛出异常。 4. REQUIRES_NEW:无论当前是否存在事务,都创建一个新事务,并在该方法执行结束后提交或回滚。 5. NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务则将其挂起。 6. NEVER:以非事务方式执行操作,如果当前存在事务则抛出异常。 7. NESTED:如果当前存在事务,则在嵌套事务中执行,如果没有则创建一个新事务隔离级别包括: 1. READ_UNCOMMITTED:允许读取未提交的数据,可能导致脏读、不可重复读、幻读等问题。 2. READ_COMMITTED:只能读取已提交的数据,可以避免脏读问题,但仍可能产生不可重复读和幻读问题。 3. REPEATABLE_READ:保证同一事务内多次读取的数据是一致的,可以防止不可重复读和脏读,但仍可能出现幻读问题。 4. SERIALIZABLE:最高隔离级别,通过对读取的数据进行加锁来防止并发问题,避免脏读、不可重复读和幻读。 总的来说,传播属性决定一个方法如何加入已存在的事务,而隔离级别决定在并发操作中事务的一致性程度。传播属性主要针对事务的调用关系,而隔离级别主要考虑并发操作的数据一致性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值