什么叫事务隔离级别呢?
那么到底什么是事务隔离级别呢?
这其实也是事务的一大特性有关系,事务的隔离性。
隔离性,就是在多个事务间会出现一个异常情况,那么针对这些异常情况,我们需要有不同的处理结论,但是不同的处理结论肯定导致的性能方面会有不一样的结果。
那么有因必有果,我们先说说,为啥会出现事务隔离级别这个机制。
在业务高并发的情况下,我们系统中业务逻辑使用到了事务处理,那么肯定在短时间内会产生多个事务情况。那么多个事务,就会有一些异常情况发生。按照王哥我的一贯风格,用一个逗比一样的场景来解读表达一下。
第一回
在一天风和日丽的下午,太阳如胶似渴,我实在渴的不行,然后看到路边有好多人围着一个水果摊,正在那里做橘子买卖交易。
这个时候,我走过去,问老板:这橘子还有多少个啊?还有200个吗?我得多买一点呢。
老板看到顾客A手上正挑着20个橘子,正准备交钱呢,然后数了数摊上的,一共180,然后告诉我:不好意思啊,只剩下180个橘子了,要不您去别的摊子看看?
我一听,算了算了,我去别的地方看看吧,都没200个橘子,不够买的。
刚走不远,那摊子老板就在远处大叫我:小伙子,小伙子!快回来,有200个橘子。
我气急败坏的过去说道:你弄啥嘞。干嘛啊。
他赶紧解释道:刚刚那顾客A,突然有急事,丢下橘子就跑了,钱还没给我。都怪我,这还没有完成的交易,我都算进去了,抱歉哈。我不应该脏读的,读了为提交的事务了。
第二回
那好吧,我为了200个橘子原谅你了,然后我说道:那你赶紧点点数,看看还有多少个橘子,够200个吗?
摊子老板认真点了一下,说道:正好,200个,不多不少。
那我要200个!正当我从我的爱马仕包中拿出一沓红票子的一系列动作的时候,一个顾客B迅速的拿起30个橘子,快速的和摊子老板完成了交易,就走了,然后我就在付钱的那一刻,说道:老板,你再点点数,一共有多少个橘子,我要付钱了。
摊子老板说到:这不刚点完吗?200个啊,我再点一下就是了,1、2、....170。诶,怎么就没有200个了?
我气急败坏到:你这不是欺诈吗?奸商!200个橘子,偷工减料,我都准备给钱了,你给钱前和给钱前前,总数都不一样!!
第三回
这个时候,一个好像是老板亲戚的一个男子开着一辆车过来了,拉了一车的水果。
我同老板正在争论呢,老板,你再给我点点数!到底有种水果。
这个时候,那个男子搬了一箱50个苹果在摊子上。
老板正点着呢:1、2。诶,!怎么变2种了!怎么有这么多水果了?。
我更火冒三丈了,到底多少,老板,你是不是数学不好!
我来点一遍!
这个时候,那个男子又搬了一箱50个香蕉在摊子上。
我正点着呢:1、2、3。诶!!!!见鬼了啊,大白天的,我出现幻觉了!!。
这个时候,那个男子又搬了一箱50个菠萝在摊子上。
老板说:我来点一遍!
老板正点着呢:1、2、3、4。诶,!怎么变4了!这怎么又多了。
我来点一遍!
这个时候,那个男子又搬了一箱50个鸭梨在摊子上。
我正点着呢:1、2、3、4、5。诶!!!!见鬼了啊,大白天的,我出现幻觉了!!。
........................
那么上述的三个现象就是三种高并发情况下出现的三种异常情况。
分别为:
- 脏读:老板把人家还没有完成的交易就算成了已经完成的交易,还没有提交的数据都是脏数据。造成了对老板,对我的困扰。
- 重复读:在摊子上面,我叫老板点了摊子的总数两遍,但是期间有人买了一袋橘子走人,导致两遍的总数不一样,导致我要买橘子的这个事务完成不了。出现异常情况。
- 幻读:在我要求下,老板一遍的点水果种类的总数,但是这个时候,那个卸货的人不停的在对摊子上的水果种类总数进行一个增加,导致我们两个点数,以为出现了幻觉。
那么也不瞎扯了,我们说说专业的描述:
隔离级别:
数据库系统必须具有隔离并发运行各个事务的能力,是它们之间相互不影响,避免了各种并发问题。一个事务与其他事务隔离的程度为隔离级别。(也就是相互之间影响的影响的程度导致隔离级别,影响程度越小,那么就说明隔离级别越大)。SQL标准中规定了多种事务的隔离级别,不同的隔离级别分别对应着不同的干扰程度,隔离级别越高,数据一致性就越好,但是并发性越弱。
- 读未提交(READ UNCOMMITTED):允许事务A读取事务B未提交的修改。
- 读已提交(READ COMMITTED):要求事务A只能读取事务B已经提交的修改。
- 可重复读(REPEATABLE READ):确保事务A可以多次从一个字段中读取到相同的值,那么就是禁止其他事务在事务A还没有执行结束期间对这个字段的操作,新。
- 串行化(SERIALIZABLE):为了保证事务A可以多次在一个表中读取到相同的行,在事务A执行期间,禁止其他事务对这个表进行增、删、改操作。可以避免任何的并发问题,但是性能降低
各个隔离级别解决并发问题的能力如下:
各种数据库对事务隔离级别的支持程度及默认值:(Oracle、MySQL)
总结:
最后面关于总结,那么我们肯定要回归到刚刚的那个场景中去,根据实际的业务场景来讲一下实际的应用方法和效果。(默认按可重复读的配置说明)
第一回:其实已经说到了,就是,叫老板点数的时候,把人家还没有执行成功的交易不要算进去就可以了,人家还没有付钱的一切交易都是假的,人家摸摸你的橘子又不卖不行吗?
第二回:方法就是,那个顾客B就压根不让他买就对了,我明明都和老板谈好了,要200个橘子,也正好200个橘子,你这个时候还买橘子给别人就不对了,我都在掏钱了,正完成交易了,再着急也得我这单完成在说。所以就是,我买东西的时候,老板不要和其他人说买东西的事情,这个时候被我和老板、橘子这三个东西上锁了。
第三回:我和老板正在数水果的种类的时候,你一个送货的不停的在对摊上的水果种类变化,我们怎么数,怎么确定?这个时候,使用可重复读的事务隔离级别是没有用的,必须配置串行化,要控制这个整个摊子上的水果的变化,也就是说我在买水果,可能买任何一种水果,这个时候,我点数,你别人都没办法对这个摊上的水果进行一个变更(读应该是可以的)。
那么最高隔离级别:串行化到底怎么理解呢?串行化也可认为为持久化。就是当所有的数据没有落地稳定,写入硬盘中,都不能读取,操作。除非没人访问了,你就可以操作了。