00:00
来看下咱们这个,这个叫事物的acid属性,这个一般呢,咱们只要说说事物的几个属性啊,这个我们就统一的叫ad了,这个acid呢,实际上是我们这四个属性的英文的单词的首字母是不是a cid,哎这样的,那么这个数据库事的这四个属性的话呢,也需要大家记住,这个在笔试当中或者面试当中也会问,因为本身呢,咱们在后边开发当中写项目的时候,咱们也会去设置这个事物,哎,主要呢,咱们到时候设置的是事物的隔离级别了,那隔离系面呢,涉及到叫隔离性,属于我们这个四个属性之一,那另外三个属性呢,也一定要大家得清楚得能记住啊,那如果说笔试让你写说数这个事物的几个属性,你得要能够写出来,而且能够简单的去解释一下,实际上呢,也不难。那先看第一个啊,叫原子性啊adicity啊,说什么叫原子性,说原子性呢,是指事物的一个,呃,事物是一个不可分割的工作单位,事务中的操作呢,要么都发生,要么都不发生,诶咱们刚才呢,实现的是一个转账操作,AA呢给BB转账100块钱,呃,最终的效果不就是要么这个转账成功了,相当于两个update都都操作了,都发生了,要么呢,就是你已经发生的也得回滚回去,相当于都没有发生,这个我们叫原子性。
01:14
能理解这个为啥叫原子不,嗯呃,因为对,因为这个原子呢,属于咱们这个物理世界当中,咱们认为是属于一个最小的构成这个这个事物的一个基本单位了,是吧,或者我们也称它叫最小单位了,也就说那还有这个原子分这个这个电子中子,对,还有在夸克呢,那就没法这个再聊了,是吧?啊这个我们就认为在化学这些当中呢,我们化学反应啊等等,那最小的单位就原子了啊,那这个原子那就意味着呢,就是你不能再细分了,就是是一个整体,哎,就要么都发生,要么都不发生,这叫原子性,哎形象的一个理解,第二个呢,叫做一致性啊说事物呢,必须使数据库从一个一致性状态变换为另外的一个一致性状态,比如我们一开始的时候呢,A ABB各自有1000块钱,然后呢,当你执行完这两个电操作以后呢,AA呢,变成900BB呢。
02:14
成了1100,但是他们的总和呢,还都是2000块钱,就是从一种状态呢,变化为另外的一种状态了,呃,也比也也也比如说咱们刚才那会举的例子,呃,这个人呢,是在河的这一岸,这呢是河的另外一中间呢,他需要游过去,需要有几个路障,每一个路障呢,你可以理解为就是一个电报操作,哎,就相当于你最后呢游过去了,相当于就是从这个一致性状态变化为这个一致性状态,后续的话,你要还有,那就是再接着一致性状态的一个变化,诶是这样一个情况。OK,这叫一致性啊,一致性那么第三个呢,叫做隔离性啊,叫isolation,这个隔离性呢,呃,稍微的难解释一点,咱们先看第四个叫持久性啊,叫持久性,持久性呢是指一个事物一旦被提交,它对数据库中的数据的改变呢,就是永久性的,接下来的其他操作和数据故故障哎,都不应该对其产生任何影响,就是一个就我们说的数据持久化一样。
03:11
一旦呢,我们执行了commit以后,这个操作就不可回滚了,那如果说我后悔了,AA转账转了100块钱,转给BB了,然后也转成了,最后还commit了,A说你给我整回来吧,哎,这时候你得看B的心情。是吧,不能说再通过数据库这个层面,我们再去roll back,这个做不到了,已经啊已经做不到了,所以呢,你只能是BB呢在主动的转账过去,那这个才是可以的啊,属于这种情况啊,诶这呢就是持久性啊,因为这个事一旦提交以后呢,就已经写死到数据库里边了,然好那么回过来呢,再看这个第三个叫做隔离性。隔离性说事物的隔离性,是指一个事物的执行不能被其他事物干扰,即一个事物内部的操作呢及使用的数据对并发的其他事物是隔离的,并发执行的各个事物之间呢不能互相干扰。
04:05
这个是最难理解的。这个刚才念完以后明白不不明白不明白就正常了,是吧?这个隔离性呢,其实有点类似于咱们前面讲Java基础的那个两个线程,或者要多个线程,我们操作共享数据的时候呢,说有一个叫线程的安全问题,对吧?哎,说你两个线程,我现在一个线程还没操作完呢,你另外的线程就来操作了,这时就会导致数据的安全问题了,诶我们当时讲的要使用同步机制解决现场安全问题,那这个隔离性呢,诶其实说的这个事情呢,跟他是有些类似的,我们现在呢,比如说这一张表,那现在咱们可能有好几个用户呢,都有权限去操作这张表,也就是说我们都有可能进行DML操作,那我现在呢,正在操作过程当中,我还没操作完呢,你别的事物就过来了,你也去操作,那这时候呢,保证咱们的操作呢,得具有一定的隔离性。就不能都都这块去改哈,这我还没改完了你就改了,但这种情况呢,对于我们数据库来讲,高并发的场景下,这种情况呢,还是很常见的啊,那有同学讲说那我就把这张表给它锁起来,类似于咱们用的那个头目监视器一样,这个你要一锁的话呢,这个隔离性这时候是是特别好是吧,但是你这时候呢,这个并发性是不是极差了,就是吧?哎,你这时候你一个事物在这操作,其他的事物全都得在这等着,哎这个隔离性哎就是隔离性最后达达到我们这个叫数据的一致性倒是特别好啊,但是呢,你这个并发性就特别的差,所以呢,在数据库事物这块呢,针对于隔离性下边呢,我们就试图给他分一些隔离的级别啊,不是说呢,像咱们讲做线上一样,说除了你不处理同步,呃,不解决线上问题跟解决,那就是相当于只有二选一的情况,而我们数据库这块呢,关于隔离级别分成了四档。
05:45
啊分成了四档,这四档呢,分别对应的叫read UN committed read committed跟repeatable read跟the laable啊叫创新化这四种隔离级别,那这四种隔离级别呢,针对的就是它要解决的问题的不一样,那有什么问题呢?上面呢提到了关于数据库的并发方面呢,有三种问题,诶我们先把这三种问题说一下啊,分别呢,叫做脏读不可重复读换读,哎脏读不可重复读换读,那先在先从这个大面上我们说一下啊这个毒未提交他呢,就是这仨问题谁也没解决。
06:24
哎,就是最糟糕的一种情况啊,叫read UN committed,谁也没解决,然后这个叫read committed呢,它仅仅是把这个脏度给解决了,这两个没解决,然后这个叫repeatable呢,是把诶脏读和不可重复读解决了,换读没解决,而我们最下边这个呢,叫串行化,把这仨问题呢都解决了,呃,叫串行化。那很显然呢,是不是解决的问题越多,从这个一致性上来讲越好啊,那一致性越好了,并发性就越差了,就是性能呢会十分的差,这个串行化呢,其实就类似于咱们Java基础里边我们说的那多个线程去操作一个共享数据,最后我们整了个同步。
07:07
啊,串行化嘛,就有点像我们中学讲的那个物理上的那个串联一样啊,本来这有好几个事物,你现在呢,本来人家可以考虑说并行的去执行的,并行执行,结果你现在呢,给人家整成创新化了,就一个执行完以后再执行另一个,再执行另一个,那这个执行的性能呢,会非常差,但是呢,数据的一致性非常好,我改完了你再改。哎,这个呢,哎,就是我们说的这个叫川音化啊,那一般呢,咱们都不会选择川音化的,因为这个性能确实太差了,那我们都会选谁呢?第一个也不能选,咱们呢,一般从第二个和第三个当中去选。啊,那这块我们就要具体看一下说,诶为什么第二个第三个就能保证我们日常的关于数据库操作这个需求呢?诶我们得先来考虑这几个问题了,好先看第一个啊叫脏读,脏读这里边呢提到了说两个事物,T1T2,哎大家刚开始可能对这个事物现在还是有点迷糊啊,你可以脑子里边暂时把T1和T2呢理解成两个线程正好呢,Thread呢,开头也是T是吧?嗯,Thread咱们这时候T呢是叫transaction啊。
08:07
诶,你可以先暂时理解成两个线程是吧,哎,我说事物你就你就想线程就行啊,说我这个事物一啊,我读取了已经被这个事物二更新,但是没有提交的字段。啊之后呢,若T2回滚呢,T1读取的数据呢,就是临时且无效的,先简单描述一下,一会咱们用这个操作的话呢,给大家演示一下啊,这呢是一个T一事五是吧?哎,这呢是一个这个咱们别这样化了,就这一张表啊,我现在T1呢是一个事五,这T2是个事五,我现T1呢去诶读这个表中的某一个字段。我读了读了假如这时候是一,然后你这个T2的话呢,我们现在对这个字段呢,进行了一个修改,比如我把这个一呢改成二了,但是我这个改了以后呢,我这个T2呢,还没有提交。我还没有提交,言外之意呢,我这个数本身就是临时的对吧,但是这时候我们T1呢,既然读的时候呢,把你这个二呢还给读出来了。这个时候呢,我们把这种情况呢,认为叫脏毒。
09:03
像这种没有提交的数据呢,其实是不应该被读到的,但是呢,这种情况呢,就给读到了,这叫脏读,1D呢,就这种问题咱们实际上是一定要解决的,1D呢,就是咱们没有一个数据库呢,使用的是这种隔离级别,因为这个呢没有解决脏的问题。嗯,好,这是一个,然后下一个叫不可重复读。说对于两个事物,T1T2啊,T1呢读了一个字段,然后T2呢更新了该字段之后呢,T一再去读这个字段的时候呢,其实就不一样了。因为你重复读了两次,发现值不一样了,这个把它称作叫不可重复读。嗯,还是拿这个来举例啊,这一个表这呢是我们这个T1这两个事物,你就先暂时想成一个线程也行啊,然后这呢是我们这个,哎,T2这个事物,现在这个表中的数据呢,是一。我们这个T1这个事呢,去读这个表中的数据呢,哎,把这个一呢就读出来了。没问题,然后这个T2的话呢,我们把这个表中的数据呢,从一呢,我给改成二了。
10:03
我给改成二了是吧,我改成二以后呢,我还提交了。我都提交了啊,那提交以后呢,说是不是数据库里边就给写上去了是吧,那写上去以后呢,我们这时候呢,我提这个事物呢,我还没有关闭我当前这个事物呢啊。我还没有关闭我这个事物呢,我没有关闭这个事物的情况下呢,我要再去读的时候呢。诶,你发现它这个二呢,哎,你这个原来是个一,然后呢,你再一读的话呢,发现它就变成二了。有点类似于我们在一个网站,比如说你这买一个商品,这个商品呢有一个呃库存,这个库存呢就剩一个了啊,然后呢,等了一会,就这时候呢,你这个链接还没有断啊,在没有断的情况下呢,我又刷新这个突然从二从一呢变成了100了,说白了就是人家后台呢,是不是又增加这个库存了,对吧?诶你这刚开始一后来读成100,诶这个怎么读了两次书还不一样呢?哎把这种不一样的情况呢,我们称为叫不可重复读。啊,其实这种情况大家觉得挺正常的是吧,所以我们一般呢,在这个使用数据库的时候呢,其实都没有解决这个不可重复,就说白我们认为这个事是正常的啊,但是呢,这块呢,这个隔离级别叫什么呀?叫啊repeatable read啊这个read commit呢,就把这个脏毒给解决了啊,然后这个repeatable read呢,他就把这个不可重复度也给解决了,他把这个不可重复度解决的,呃,效果是什么呢?就我现在这个其一这个线程啊,呃,其一线程这个事物我们现在读这个时候呢,它是一,然后你T2这个这个事物的话呢,把它给改成一个二了,改成二以后的话,你还给commit了,你提交了,提交以后呢,其实按说数据库已经写成二了啊,但是我这个T1这个事故还没有关,在没有关的情况下呢,我再重新再查一次,还是一。
11:45
只要你还在这个事物之内呢,你就还是以,除非呢,你把这个事物你关掉,关掉以后呢,我再重新再开一个新的事物了,我再去查,这个时候呢,查到的才是二。就是只要你还在这个提这个事务当中,我们还占用了对你这个表的一个操作,即使别人提交了,我们再查,还是以保证了你两次查的时候呢,重复执行的情况下呢,还都是一个数,这就叫repeatable可重复读嘛。
12:13
这个呢是咱们讲这块呢,算是比较难的点啊,好,再来这块呢,需要大家脑子里边得得保证保证保证你现在是最清醒的啊,因为下来你在看的时候呢,这块还是稍微有点绕,然后第三个呢,叫做换读说呢两个事物T1T2 t1呢从一个表中读了一个字段。然后T2呢,在该表中插入了一些新的行之后呢,如果说T一再去读这个,呃,同一个表的时候呢,会多出几行。数据对还是这个,然后这块呢,我们通过这个题呢,去查这表,比如我查这表一共有多条数据啊,一查发现有100条数据,然后这时候我们这个呃,另外一个呃事物他就把这里边呢,诶多加入了一些数据,加上一些数据以后的话呢,我们这时候T一再去查呢,发现诶怎么多了几条数据。哎,跟出现幻觉一样,哎,这叫幻读。
13:02
这叫换堵啊,那么我们这个串行化呢,就相当于把这个换堵的问题也给解决了。啊,也给解决了啊,就相当于是我们T1现在只要你还在这个呃,事务当中啊,即使这个T2提交了数据,我们这块再去查你还是100条数据。除非呢,你把那个T你关掉,就跟咱们浏览器一样,你把你浏览器关了,你再重新进来,相当于一个新的一个事物了,对吧,你再去查的话呢,才是这个,比如说加了三,那那就变成103个了。呃,其实通过刚才讲解大家也会发现,其实这个不可重复图,跟这个换图呢,我们觉得都是不是一样的了啊,这个叫更新,这个叫插入啊。它不一样,这个是专门针对update的操作,这个呢针对的是这个insert的操作啊,这个不一样,哎就是这两个操作呢,我们认为其实是可以接受的,你像咱们平时打开一个浏览器,你这个商品呢,现在就一个,然后呢,我们这块呢,你就一刷新啊,这个呢,变成100个了,人家补库存了,或者人家这个人一开始100个你觉得不着急,结果一刷新就剩一个了啊赶紧买是吧,哎,就是这块呢,你刷新的时候呢,因为它后台呢,进行过相关相关的一些这个更新数据了,这个问题啊,这一个另外一个的话呢,就是比如你现在呢,去想查一下这个叫。
14:12
呃,小米前两天昨天吧发的那个红米NOTE8PRO是吧,性能确实我看可以啊,还挺便宜啊,还发了一个红米的电视,比如你这块你去京东上你去搜红米电视一搜没有。然后等了会儿一刷新出来了,所以相当于呢,刚开始那一瞬间呢,就是后台呢,没有这个数据,后来呢,人家后台这块呢,把这个数据呢,给你隐私进去了,人家一刷新就有了,这个我们认为很正常啊,你要说这个我们把这种隔离级别给它调成叫创新化,那是什么情况呢?我这一刷新没有,再一刷新还没有,你这时候还在这个连接当中,我这时候把浏览器,其实人家已经后台更新了啊,但由于你还在这个事物当中,所以你就是看不到,你把你浏览器一关,再开一个浏览器再一刷新出来了。啊,这个呢,就相当于是你这个串行化隔离性一致性特别好啊,但是的话呢,我们认为没有必要。
15:02
哎,所以这块呢,我们就提到了,主要集中在就是这两种,那其实这两种的话呢,我们说其实这种就行,就是我们其实只需要把这个脏度问题解决就可以了,像人家没有提交的数据呢,你肯定是不要读取的,就不要读到,你读到了不合适。啊,它是一个临时的数据,因为人家随时可能回滚嘛,毕竟没提交嘛,就有可能回滚,所以你查这个数据呢,就是无效的,所以最好呢,不让用户看到这个脏毒的数据啊,那下边我们就提到了,针对这个Oracle和myle来讲,大家看一下,说Oracle的话呢,它其实虽然我们规范了说四种隔离级别,但是对于Oracle来讲,它只支持两种。嗯,Oracle呢只支是两种,就是叫呃,这个read committed和这个串行化,那么默认情况下呢,它是用的叫read committed,那这个大家记住它默认的叫read committed,然后对于MYSQL来讲呢,它支持这四种隔离级别。那么MYSQL呢,默认的呢,是用的这个。叫repeatable read,相当于它这个叫什么,并发性叫Oracle呢,差一些。
16:08
越往下并发性越差,什么越好?大家有安全性,哎,叫一致性越好,一致性越好啊,那就意味着咱们Oracle呢,比咱们的myle呢,叫并发性要好,但一致性呢稍差一些,呃,因为主要这里边涉及到一个叫不可重复读的问题,就是看他俩一个解决了一个没解决的事。啊,这个呢,就咱们把这个呃,提到了叫acid属性中的这个隔离性,隔离性呢又分成了四种隔离级别,针对的是三种并发问题,到底解决到什么程度了,规范出来的,以及呢,在数据库当中,诶,我们两种常见的数据库,他们默认的隔离级别是什么?以及呢,我们下边还提到了,咱们通过命令行的这样的指令,我可以查看一下呃,当前数据库的隔离级别是什么,然后还可以设置当前这个连接的啊隔离级别,以及呢,设置整个数据库系统的一个隔离级别,那都可以来做相应的一些修改和获取,这就相当于是我们在查询,就类似于我们说一个属性的get方法一样,啊下边呢,就相当于是在set去设置它的隔离级别。
17:16
那么刚才这个事儿呢,只是我们通过文字的方式做了一个描述,下边呢给大家做一个演示。
我来说两句