Spring事务、隔离级别、传播特性通俗理解,没懂就是没认真看

Spring事务、隔离级别、传播特性通俗理解,没懂就是没认真看,第1张

什么是事务?

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

这是最经典的事务了,任何一步如果出了问题就要恢复到最开始的状态。如果说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也没有事务,以非事务运行。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/798805.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-06
下一篇 2022-05-06

发表评论

登录后才能评论

评论列表(0条)

保存