Spring事务、隔离级别、传播特性

什么是事务?

事务其实是数据库操作的最小单元,一个事务包含一系列操作,这些操作要么都执行成功,要么都执行失败。
啥意思?来看张图:

 

这是最经典的事务了,任何一步如果出了问题就要恢复到最开始的状态。如果说B账户加1000出了问题,但是A账户已经扣了1000,那肯定是有问题滴,所以需要回滚到最开始的状态;如果没有出问题,则事务提交。

事务的四大特性
想往深处了解事务就先了解下事物的四大特性
1.原子性:事务中的所有操作要么全部成功,要么全部失败。
2.一致性:事务执行之后,前后的状态需要保持一致。如:A给B转钱后,AB的金额总和要和最开始一样。
3.隔离性:两个事务之间不会相互打扰,后面会针对这个仔细讲。
4.持久性:事务完成之后,数据不会丢失,会持久化到数据库中。

事务的隔离级别
事务的隔离性可以分为四个隔离级别:读未提交(READ_UNCOMMITTED),读已提交(READ_COMMITTED),可重复读(REPEATABLE_READ),序列化(SERIALIZABLE)

读未提交(READ_UNCOMMITTED)
一个事务可以读到另外一个事务未提交的记录
啥意思,先看张图:

 

A事务插入数据之后,B事务就去能够读取到所插入的数据,但是之后A事务去回滚。这时B事务读到的数据就是脏数据,称为脏读。并且也会有不可重复读,幻读的问题,具体下面会讲。

读已提交(READ_COMMITTED)
一个事务只能读到已经提交的事务,不能读到未提交的事务。
啥意思,如图

 

B事务首先查询一次数据,后A事务修改数据并且提交,B再查询一次数据发现和第一次查询的记录不一致。这个问题称为不可重复读。此时脏读则不会产生,但还有幻读的问题。

可重复读(REPEATABLE_READ)
一个事务可以多次从数据库读取某条记录,而且多次读取都是一致的。
啥意思,如图:

 

B开始去读取一系列记录,之后A向数据库插入了一条数据,之后B再去查询会发现后面读取的数据多了一条,此时会认为第一次是不是看错了,导致了幻读。可重复读与读已提交的区别在于:可重复读针对增删,读已提交针对修改。

序列化(SERIALIZABLE)
是最强的隔离级别,它会在所有级别上加锁,事务是串行进行的,如A执行完再执行B。此时可以防止前面的三种问题,但是会造成性能的下降。

事务的传播机制
什么是事务的传播机制?

其实就是两个方法,一个方法调用了另一个方法,其中一个方法有事务,那么另一个方法的事务是新建还是怎么样,用传播机制来规定。
有七种传播机制,分别是:

REQUIRED,

REQUIRES_NEW,

NESTED,

SUPPORTS,

NOT_SUPPORTED,

MANDATORY,

NEVER
下面讲解以A方法调用B方法为基础:

 

REQUIRED
翻译过来叫必须的,意思是如果有事务就加入事务,没有的话就新建一个。如:B使用了
@Transactional(propagation = Propagation.REQUIRED)
那么分为两种情况:
1.A有事务,那么B就用A的事务,AB任何一方出现问题都会回滚。
2.A没有事务,那么B就新建一个事务。

REQUIRES_NEW
翻译过来叫必须是新的,意思是新建事务,如果存在事务,那么把当前事务挂起。如:B使用了
@Transactional(propagation = Propagation.REQUIRES_NEW)
那么分两种情况:
1.A有事务,那么B将A的事务挂起并新建一个事务运行,运行完毕之后再恢复A的事务。
2.A没有事务,那么B新建一个事务运行。

NESTED
翻译过来叫嵌套的,意思是如果当前存在事务则在嵌套事务内执行。如果没有事务则执行REQUIRED类似的操作。如:B使用了
@Transactional(propagation = Propagation.NESTED)
那么分两种情况:
1.A有事务,那么B新建一个A的子事务,A异常会回滚AB,B异常只会回滚B。
2.A没有事务,那么B新建一个事务运行。

SUPPORTS
翻译过来叫支持,意思是如果当前存在事务,则加入事务,如果不存在事务,则以非事务运行。如:B使用了
@Transactional(propagation = Propagation.SUPPORTS)
那么分两种情况:
1.A有事务,那么B就用A的事务,AB任何一方出现异常都会回滚。
2.A没有事务,那么B就不用事务,正常运行。

NOT_SUPPORTED
翻译过来叫不支持,意思是以非事务运行,如果存在事务,则把当前事务挂起。如:B使用了
@Transactional(propagation = Propagation.NOT_SUPPORTED)
那么分两种情况:
1.A有事务,将A的事务挂起,B以非事务运行。
2.A没有事务,那么B就不用事务,正常运行。

MANDATORY
翻译过来叫强制,意思是如果当前存在事务,则运行在当前事务中,如果不存在事务,则抛出异常。如:B使用了
@Transactional(propagation = Propagation.MANDATORY)
那么分两种情况:
1.A有事务,那么B就用A的事务运行。
2.A没有事务,那抛出异常。

NEVER
翻译过来叫从不,意思是以非事务运行,如果当前存在事务,则抛出异常。如:B使用了
@Transactional(propagation = Propagation.MANDATORY)
那么分两种情况:
1.A有事务,那么抛出异常。
2.A没有事务,那么B也没有事务,以非事务运行。
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
事务隔离级别是指多个事务并发执行时,一个事务对其他事务的可见性和影响程度的控制。Spring框架支持四个事务隔离级别: 1. 未提交读(READ UNCOMMITTED):最低级别,一个事务可以读取未提交的数据,会导致脏读,不可重复读和幻读问题的出现。 2. 提交读(READ COMMITTED):一个事务只能读取已提交的数据,可以避免脏读问题,但可能导致不可重复读和幻读问题。 3. 可重复读(REPEATABLE READ):在一个事务中多次读取同一数据时,结果保持一致,避免了不可重复读问题。但仍然可能存在幻读问题。 4. 串行化(SERIALIZABLE):最高级别,通过确保事务串行执行来避免脏读、不可重复读和幻读问题。但会降低并发性能。 传播机制是指在调用多个事务方法时,如何处理事务传播Spring框架提供七种传播行为: 1. REQUIRED:如果当前没有事务,就创建一个新事务;如果已存在事务,则加入该事务。 2. SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方法执行。 3. MANDATORY:强制要求存在当前事务,如果没有事务就抛出异常。 4. REQUIRES_NEW:创建一个新事务,并暂停当前事务(如果有)。 5. NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,则将其挂起。 6. NEVER:以非事务方式执行操作,如果当前存在事务,则抛出异常。 7. NESTED:在当前事务的控制下执行一个嵌套事务,如果不存在当前事务,则创建一个新事务。嵌套事务可以独立提交或回滚,但在外部事务提交时才会生效。 通过选择合适的事务隔离级别传播机制,可以确保事务的数据一致性、安全性和性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值