00:00
好,那么刚才呢,咱们就把这个的这个呃,设计的一个规则,以及呢,MVC整体的操作流程啊,咱们就说清楚了,那如果呢,我说完之后呢,大家赶紧很清楚啊,一目了然啊,那特别好,那下边呢,我们再通过一个例子呢,让你更清楚,那如果说呢,这个刚才呢,讲完这两个结构以后的话呢,感觉有点迷糊啊,你也没有必要呢再翻回去再看一下了,我们可以直接呢上例子啊,讲完这个例子以后呢,哎,如果呢,你清楚了,那也是可以的啊,或者这个例子呢,更容易的让你去清楚。啊,这是一个点,那另外的话呢,就是说,呃,在面试当中啊,如果提到了说我们这个macc的具体的一个操作流程了,大家你可以去说刚才我们讲到的这个的这个规则和我们这个整体流程,你也可以呢,呃,以这种举例子的方式呢,去讲解也OK啊,因为这俩呢,其实举例呢,只是对上面这个结构的一个啊具体的一个展示而已,好那么我们具体来讲一下这个例子。说呢,我们有一个大背景啊,说我们在student这个表里边啊,咱们有一条记录,这个记录呢,呃,是ID为一的这样的一个数据,是由我们事务ID为八的这个事物呢,帮我们插入的啊在这个大背景下我们去讲啊,那么讲的话呢,我们分成了这样的两个大的方向,主要原因呢,是因为m macc,它只在啊提交和可读这样两个隔离级别下呢起作用,所以呢,我们就分别呢,在这两个隔离级别下呢,我们去讲一下它的一个啊这个整体流程对吧?好,那以及呢,我们说呢,Repeatable read呢,它还可以解决读的问题,那我们顺便呢,把这个读是怎么解决的呢也说清楚。
01:26
OK,好,那我们先说呢,叫read committed这个隔离级别。刚才呢,我们在上面讲的时候呢,明确说了啊,因为它很重要,我又重复了一遍说呢,这个read committed,在这种隔离级别下呢,我们这个事物啊,你每select一次呢,我们都会生成一个。啊,都会生成一个,好,那么基于这样的场景来,我们下边说我们呢,诶有两个事物啊,一个ID呢叫十,一个ID呢叫20都呢,来考虑对我们这个ID唯一的这样一条记录去修改啊,那么最初的情况下呢是50。他呢,呃,针对这个ID唯一的这条记录呢,做了一个更新,张三改成李四啊又改成王五了,然后这个十五二十呢,呃,目前呢,是什么也没做。
02:09
啊为为什么我这边写的说更新了一些别的表的记录呢?呃,咱们上面也说了啊,咱们呢,一个事物的ID呢,是由我们系统呢来进行分配的啊,如果呢,你是一个增删改的行为,我们会呢,给你分配一个具体的ID值依次递增的方式来分配,但如果呢,你要是一个查询的行为呢,我们这个ID值呢就是零。啊,就是零啊,所以这块呢,我写的这个。这个20呢,呃,这个为了让它有一个数不是零,所以呢,就是诶更新一些别的表的记录啊,让我们系统呢,给我分配一个数啊,仅此这样一个作用,好那么我们这块呢,操作执行完以后的话呢,在我们整个这个ID唯一的这个记录上呢,是不是会形成这样一个结构啊啊,真的就是我们安度的这样的一个整体的一个版本链啊好,那么基于这样的一个场景呢,咱们下边来谈一谈啊,来一谈我们现在要做这个查询了是吧?嗯,现在的话呢,我们在瑞committee的这样的一个隔离级别下有一个事物啊begin了。
03:00
然后呢,它呢叫selecting from student这个表,然后呢,Where ID等于一。注意此时的话呢,我们这个transion啊,这个ID为十的和20的这两个都没有提交,都没有提交的情况下呢,我们去读以提交这样的一个隔离级别,那我们查出来是谁啊,是不是大家呢,应该都知道是不是查出来是张三呀,那咱们下边呢,其实就在解释为什么查出来的是张三对吧?好,那我们来分析啊,首先的话呢,我们这呢,是不是写了一个select的操作啊,你这个begin它开启个事物啊1SELECT操作,我们现在是不是就会生成一个read,好那么生成review啊,就是针对你当前这样的一个快照,这个快照里边呢,记录的这样几个信息,首先呃,谁生成的我呀,哎是我们这个读的这样的一个事物,所以呢,你的ID呢是零对吧,那么当前这个呃生成呃读的时候呢,生成一个快照的时候呢,我们哪些事物活着呢?诶十和20是不是这两个呢,是活跃的,所以我们这个列表里边呢,有ID为十的和ID为20的这两个事物。啊,那这里边比较小的这个呢,就是十倍,呃大的呢,哎大呢就是我这呢写成二一,其实主要呢,我们可以理解为呢,就是除了这两个之外,你可能还有其他的一些,呃这个这个呃就是系统用过的事物啊,但是都不会超过20,那这个呢,是我们目前呢最大的一个事物了,所以呢,我这就写成21了啊后边呢也同样如此啊,我就不每次呢都解释了。
04:17
好,那么在这样的一个场景下啊,Read的这个场景下,下边呢,我们开始去判断,那从这个版本链中呢,我们去挑选这个可见的记录,那首先呢,我们挑的是不是就这王五这条记录啊啊,那这个记录呢,我们看到这个是十对吧,这个十的话呢,首先啊,它跟我们这个呢不一样。啊,你要一样的话呢,肯定我们就把这个王五就读出来了是吧?哎,不一样啊,然后呢,你会发现这个十呢,是不是在我们这两个,呃,在我们这个列表当中啊呃,首先呢,在这个列表范围当中啊,其次的话呢,你还恰好就在其中这个里边,那就意味着我们当前这是活跃的,说明我们这个事物呢,是还没还没有提交啊啊既然没有提交,你能把这个王物查出来吗?哎,肯定不行嘛,诶咱们不是上面也提到这样个规则了,是吧?不行,那不行呢,是不是就要找下个版本,那下半一看又是十,那是不是又不行。
05:01
啊,还在这里边儿呢,还不行是吧,那再往下找是不是找到八了,哎,八注意看啊八呢,呃,不在这个活跃里边。啊,不在我们这个活跃里边啊,那比这个事相当于还小啊,相当于我们这个事物呢,它一定是之前已经提交过的一个事物了,那既然你已经提交了,那我就应该把这个记录呢读出来,所以最终的结果呢,就是把张三呢给读出来了。哎,就是这样一个场景。啊,所以张三就出来了,好,那么接着我们再去修改之后呢,我们把这个呃,事物ID为十的这个事物呢,我们给提交了啊,咱们做了一个commit提交,OK,那提交以后呢,呃,紧接着我们再到这个事物ID为20的这个事物当中呢,我们去更新了一下表记录。那这里边儿呢,我们把这个ID唯一的这个记录呢,改成这个前期改成这个送八啊,操作完以后啊,目前呢,我们这个表当中看到的是不是就是这样的一个情况。啊,在我们这一条记录上是吧,好,那么针对这个情况的话呢,我们现在呢,还是我们刚才那个读的那个失误啊,我又读一次啊,就是你在你这个,呃,十五十十五二十这块都操作完以后的话呢,我又读一次,我又读一次,注意咱们现在是叫read committee的这样一个隔离级别,每读一次是不是就生成一个read。
06:09
啊,所以这时候呢,我们在读的时候呢,又生成了一个read view,好,那么我们又生成这个啊,咱们现在来看啊,此时的这个read里边,那我们把这个十呢,已经提交了,是不是只剩20了。对吧,然后呢,这个呃,你这个读嘛还是零,然后这个呢,还是二一啊这个呢是20,这都没问题是吧?好那么在这个场景下的话呢,我们来看啊先呢考虑的是这个20 20人一看,哎哟,在这个列表里边还活跃的是不是这个呢,就不应该把它读出来,因为人家还没提交呢,还活跃着呢,是吧,你读一提交嘛,你不能用它这个送八了啊,他不行,再往下走啊,这个20还是20还不行是吧?再往下走是不是找到这个了,哎,这个呢是十。十的话呢,一看诶不在列表里边,而且呢,比例率表这个数据还都小是吧,那相当于呢,你这个呢,就是已经提交过的了。啊,就是比我们这个值量相当于小,那比例值大有没有可能会大呢?呃,如果要是大的话呢,说明就是你生成这个read view的时候呢,然后人,然后人家呢,是不是后来哎去做的修改的一个ID了,那你后来的你更不能去用了,是吧?啊那这时候呢,他得比我们这个呢,相当于是得得得小啊还小啊那不活跃了,还小那就说明他是之前我生日这个read呢,诶之前啊你诶的一个事物啊已经提交了,那我们就应该把这个王五这个数据呢,是不是得查出来,诶所以这时候呢,我们查到这个数据呢,就是王五。
07:29
啊,就这样个情况,好,那么如果以此类推的话呢,咱们把这个呃,事物ID为20的这个,其中呢,他也给提交了,诶他要也提交的话呢,我们现在这个活跃列表里边就没有它了,那没有它呢,这时候你是20,然后这个相当于我们又不活跃啊,然后这个呢,比这个还小,相当于我们是不是就把它呢给。查出来了是吧,现在这个送八呢就能出来了,哎,就这样一个场景,好这个呢,咱们针对的是一个叫诶read啊committee的这样一个场景。哎,这个清楚以后呢,那咱们顺着呢,就直接往下说啊,直接往下说。
08:00
呃,我们现在呢,是在这个repeatable的这样的一个隔离级别下。啊,在repeatable这个隔离级别下啊,说呢他只会啊,我又强调一下,只会在第一次执行查询语句的时候呢,生成一个啊之后呢,你在查询的时候就不再给你生成了啊就这样场景,好,那我们还是回到这个最初的这个场景啊,一开始呢,是不是只有这一条记录啊。嗯,这个在我们最初的时候啊,只有这一条记录,然后啊,我们呢,对接一下啊,现在提到这个啊,我们还是这个事物ID为十的啊,这个事物呢,我们去update啊两下。然后呢,呃,下边这个事呢,啥也没做,目前我们看到呢,还是这样一个场景。啊,这个把它盯一下啊,把这个往这放一下好,那么在这种场景下呢,我们现在呢,实行这个叫repeatable这个read,然后它这块呢,其实跟咱们上面这个就一样的这个情况了啊呃,在我们这个事物开启以后呢,我们做这个select啊1SELECT,首次select我们会生成一个。啊,那这是我们查到的这个数据是谁呢?应该是张三了啊,其实这个过程呢,跟咱们上边讲的那个read committed的这个过程呢,其实是完全一样的啊。
09:04
就是下边这个代码,这个这个说明呢,都一样,你看还是十跟20啊,这个都一样,然后呢,这时候我们先去找这个是十啊11看这活跃的是吧,呃,这这不行了,然后这个呢,你看还是是也不行,所以这个八呢,诶不在这里边,然后比这个还小,然后呢是已经提交了,所以我们把这个张三就查出来了,诶这块呢,其实跟我们刚才讲的read committed的啊,第一个环节呢,其实是一样的啊,这没啥可说的,然后紧接着的话呢,我们把这个哎,TRANS30的这个事物呢,人家给提交了。然后呢,我们这个喘塞是20啊,这个事物ID为20的这个事物呢,它呢做了两个更新啊,就跟我们上面那个大体的场景呢是一样的啊,那么在这个场景下。注意在这个场景下,现在呢,我们刚才那个读的那个事物呢,他又读了一次,注意这时候读的话呢,咱们因为是在repeatable read的这个隔离级别下,所以你就不要再去生成了。哎,所以呢,这时候我们在这个隔离机片上,我们这个read是谁啊,还是你刚才的这个。哎,还是这个read好,那么这个呢,诶是不是就完全的不动的,我就把它就拿过来了啊,那么在这个里边呢,咱们去考虑这样的这个行为了。
10:08
啊,你看这时候我们说这是哎哎这样啊,哎20行不行啊,21看在里边不,哎在里边那你能用吗?不能用吧。对吧,诶相当于你这我们看到的呃,还是活跃的,事实上,诶事实上呢,它现在也确实活跃的是吧?诶这也不能用,哎这个20也不能用,然后下边呢,我们查这个十,这个十的话呢,诶虽然说我们这个transaction是十呢,已经提交了,但是我们现在用的这个呢,是你首次提交的时候,呃,首次select时候的那个,它还有十呢。诶,所以呢,你会认为说呢,它还活跃着呢,是吧?诶总之的话呢,只要在这个列表里边呢,我们是不是就不能用了是吧,那不能用这个是不是也不能用,所以我们是不是就找到这儿了,诶这个八呢不在这里边,而且比这个还小,那相当于他已经提交过了,诶相当于我们是不是就把张三给查出来了。对吧,那整体上来看的话呢,相当于是我们在这个可重复读的啊,这样的一个隔离级别下呢,啊,你第一次读啊是张三,第二这个事物没提交啊,第二组还是张三,哎,这不就达到了一个可重复读这样的一个效果嘛,你就规避了不可重复读这样的一个并发问题。
11:09
啊,应该很清楚是吧,很清楚好,那那我们要接着再说呢,我要是把这个transaction为呃20的啊,这个事物呢,我也提交了,然后把它也提交,你把它也提交呢,我们这块呢,再去select啊无所谓,你再select是不是用的还是第一次的那个啊第一个在read里边是不是就有20,只要有20,你是不是就不能用它,所以还是用的张三,哎,所以呢,只要你这个事物没提交,用的都是第一次的,你就不会把十跟20的都查出来,所以永远是张三,所以呢,哎,就是可重复读嘛。哎,这样一个意思。啊,明白是吧,好,那这样的话呢,我们就把这两种隔离级别下的问题呢,是不是就说清楚了。
我来说两句