00:00
下面我们来研究一下这个塞身缓存。为了进行测试呢,我们需要在数据库里边先添加一条记录。之间随便选一个。写代码。栽。Edge。从数据库里边把ID那个一的记录获取出来。反转。做一个感应。不行。我们看到发了一条select语句,同时把这个结果打出来了,就跟我们预期的是一样的,往下看。
01:06
我再获取一遍。想转,然后的话呢,这个结果打一下。保存,我的问题是44行。是不是还像41行那样也来发送一条select卷呢?会吗?就是说把这个方法一执行,会发几条词后语句。咨询一下看结果。连续两个打印,发了几条色啊?是不是就发了一个呀。诶,那我为什么我41行调这个盖的方法发了一条SQ语句,为什么44行就没发这个SQ语句呢。为什么?
02:00
因为有。塞身的缓存存在。看PPT。我们先来看这个图。41行的时候呢,我执行了一个second that,那这个时候它的确是会去查询数据库,然后把这个news对象得到,得到之后这个引用给到了我这个news啊,同时还会把这个引用给到我的session缓存。就是说这个时候啊,这个news对象的话呢,有两个引用,一个是news,一个是再生缓存啊,我说44行再进行查询的话,他会他先回来看这个缓存里边有没有,如果缓存里边要是有的话,就不查数据库了,而把缓存这个引用直接。给到我的这个news to,所以说。指向数据库发了一条SQ语句。30缓存在三帧接口的实现中,包含了一系列的Java集合,这些Java集合构成了三声缓存。因为缓存的话,你需要把这个。
03:05
对象放在一个数据结构里边吧,哦,它是一切式的Java集合,只要三帧没有接触生命周期,而且在没有清理缓存的情况下,那么存放在缓冲的对象就不会解除生命周期,啥意思嘞?即便是我news跟news to都不引用这个对象了,那这个对象也不会成为垃圾,因为我这个缓存里边。呃,还有引用的,引用它呢。缓存可以有效的减少hamlet应用程序访问数据库的频率,这实际上是我们提高运行效率的一种方式。实际上呢,这个session缓存我们也称为half的一级缓存,到后边我们对应的还会有一个二级缓存,一级缓存session级别的,二级缓存呢,Session factory级别的,那我们后面再说这里边啊,我们提到了一个什么呀,叫没有清理缓存的情况下,那我们下面就来看一下。
04:06
如何对塞单的缓存进行操作?Harm提供了三个方法来对session缓存进行操作。第一个叫。Flash,然后是refresh,然后是clear clear,这个clear clear就是我们前面说那个叫清理缓存,先说第一个flash。Flash大家看到哈,我这个箭头呢,是有缓存指向数据库记当我调session flash方法的时候。它会强制使数据库的记录跟缓存中对象的状态保持同步。就是说哎,开始的话呢,我进行了一个查询。然后我就我这叫flash方法的时候啊,我我会看一下。缓存里边这个对象的这个状态,包括各个属性啊,跟数据库里边这个记录是不是一致,不一致的话,我会发送对应的词后语句,让它保持一致,那可能是update,也可能是delete。
05:13
那也可能是insert。测试一下。Fashion platform。At。首先获取一个对象。40行呢,一定会发一条。这个在前面我们已经很清楚了,好了,我在41行写这样的代码,Author啊。我改一个叫Oracle。
06:02
保存。数据表这个值啊,还是散。测试一下看缺口。我们看到什么呀,发了一条select。底下是不是还有一条update呀,看到了吧。诶,这个update是怎么回事啊?这个实际上就是。Flash。就是掉了三的flash方法怎么回事呢?40行,我把这个那个对象从数据库里边获取出来,然后我改了一个属性,那我整个这个过程是在。三生的生命周期里边,而且还开了事物,这不是吗?这是一个session。然后开了事务,然后执行的我呃这两个代码,然后的提交事务关闭session,所以说我修改属性的话呢,这个时候呃。
07:02
Session是可以感知到的。他发现缓存中对象的这个状态跟数据库已经不一样了,于是在调commit,呃,在真正提交事务之前,它会执行一个flash发送。这个。After。看数据表哈,这个的确是变了,好了我们再改回散,我们编一下代码。Byal。Control d。走。我们看到。178行是提交事务,我一百七十五行有个什么呀。有一个叫before commit,在commit之前要干点什么?等一下。抽象方法,比如t bc transaction。哎,我们看到。
08:00
他会来管理这个flash。等一下。T找到三。看到这不是标了session的一个flash方法呀,这个session呢,就是session的一个实现。更新一下源代码。这是Oracle啊。四十三十三号也打一个断点。Debug。我们注意到现在在这个33行停的时候的话呢,我只发了一个select,就是说我真正调这个news.set auto的时候,它并没有发生update。往后走。到了这个。Before transition commit。这个时候也没有发。再往后找。
09:02
到哪了?啊,到三的flash方法之前了,往下执行一步大家看。这个时候会发update。看数据库。是不是还是or口啊,它并没有进行修改,为什么呀,我语句是发了是吧,但是我还没有提交事务。我还没提交事务呢。再下一步。哎。要提交事务了,还没提交呢。还是这样。往下一行看一下提交事务。再看结果。改了看到了吧,这是整个这个流程。所以说。我们再调这个可方法先过吧。回来。Harmon test,诶,我们在调这个commit方法的时候呢,他先会进行flash,然后再提交实物。
10:05
写一个笔记。Flash。值。数据表中的。记录。和。记录。和缓存再生缓存。中的对象的状态保持一致。为了保持一致的话,有可能会向数据库发送对应的词汇语句。对了。保持一致,则。可能会发送对应的。Circle。
11:01
什么叫可能啊,有可能我在到flash方法的时候呢,我缓存中的这个对象状态跟数据库里边一模一样,那我就不发送呗。第一个问题。盗用。BY的革命的方法。中。我们看到在。这个方法中。先进行flash。先调用。Flash。方法带。提交注。就是一个,嗯。Flash的一个时间点啊,在调commit方法的时候,他会先调用flash,再提交事物,第一点,第二点我们要注意一下plus plussh。
12:08
方法哎,会发送SQ语句,可能会发送SQ语句。可能会发生这个语句。不会提交。是刚才我们已经看到了,现在的话显示的对象Fla,看一下section.large。Out。49行来一个顿点H3。数据表里边。出去表里边也是散是吧?对,把这个改为二口。有一个。第八个。
13:01
目前的话呢,就是一个select数据表里边这个是三。嗯。改为Oracle,注意哈,49行。找一行,大家看是不是发了update呀,语句发了数据表里边的记录并没有发生变化,因为还没有提交事物呢,我直到提交事物的话。我们才会看到数据表里边这个状态是发生变化的。停掉,回来。三啊,我们当然可以显示的到这个flash,到这个SH,它仅会发O语句,但不会提交事务。需要注意的点。第一个。除了。Section这个革命的方法会先掉这个flash或显示掉flash以外,还有什么情况下它也会来进行flash操作呢?
14:04
弱。哎。Session暂未提交事务。或显示。调用。SAN are flash。方法。之前也有可能,也有可能。会。进行flash操作。啥意思啊,就是说我没到这个革命方法,我也没显示掉这个方法,它也有可能进行flash。什么情况呢?
15:01
一种情况。两个例外情况,第一个情况来执行。SQL或QBC。查询啊,要执行这个HQL或者QP查询的话,我要求我查的这个对象必须是最新的状态,那这个时候他就得先flash一下,只有这样我才能够保证从数据库里边查这个对象是。最新的。会先。进行操作。一。得到。数据表的最新的记录。瞧吧。保存。是Oracle。H3哈,哦,我进行一个查询操作,这个KL跟这个QPC呢,我们后面会讲到。
16:06
我们看一下,我要得一个news news two等于三点,当然不是get的话是没用啊。因为这个时候他就获取的就是缓存里面那个数据是吧。R。6.plus。点unique result只有一条记录吗?走。啊,我第一个news。注意我在54行加一个端点。Bug。前面还是只是执行了一个操作。好了,现在我要用这个QBC的方式查一下这个对象,下一步看。
17:09
是不是执行了一个update呀,因为我要保证我查的对象是。最新的,虽然说你还没提交事务,为什么呀,因为我这个查询不也是在这个事务范围内吗?我必须保证在这个事务范围内,我查的对象是最新的,于是他就先必须得给我一个update,但是同样嗯,这个也没有进行更新,没有。查的这个6TWO是什么呀?是一个最新的状态,这个已经改为凹口了,而这一块这个还是。是吧,那你要一直往后执行的话。这是我们前面加的顿点,那这个时候呢,这个会发生改变。那你通过这样的方式,那。通过这个QBC查完之后,这个结果就是一个最新的状态,这是一个例外的情况。
18:07
这样一个例外的情况。我们说呀,这个flash呢,是为了保证数据库里边记录跟缓存里边那个对象保持一个同步的状态,那我要是调save方法呢。进行插入操作。一个public。Session的flash方法。At。大家注意看哈,我创建一个news。开吧。妞。
19:03
OK。我执行一个保存操作,Save。我是用这样一个操作。我把这条记录先清空。先看效果。这个的话呢,的确会执行一条insert,这条记录的确是进得来,这个我们都很清楚。好啦,我回来。要说的是。其实是应该在盗用。Transaction commit方法的时候才进行。Insert这个语句的发送。那现在是不是这个情况呢?我清空。我把这个断点啊整理一下。
20:01
干掉。回来。我只在。Commit这块留一个端点。Debug一个。走。大家看可密这块停下来了吧,实际上是不是在可密之前他已经执行了颜色的呀。你不是说在commit的时候它才会进行flash操作吗?才会发送这个SQ语句吗?为什么之前就执行in色呢?我们讲了哈,这是一个例外的情况,走啊,停住,这个时候这个记录并不会插进来。回来。这是一个例外的情况说。弱。数据。地路。地路的ad是由。
21:00
底层数据库使用自称的方式生成的,则。在盗用方法后。就会立即。发送颜色的一个。就是这个时候啊,会立即盘一次说为什么呀,因为。因为自由方法后。必须保证。对象的ID是存在的。这也是一个例外。好吧,说我调完这个save方法的话呢,我必须保证这个ID是存在的,而且有效的。那我为了。
22:04
得到这个ID的话,我只能去执行那条银色的语句,我才知道这个ID是几吧?数据库底层帮我生成吗?那如果这个ID是由哈给你生成的话,你会看到。我是在。调commit方法的时候才发送对应的SQL语句。现在的话呢,我们把这个生产力的方式呢,改一下,改成一个KO。这种方式的话呢,后边我们可以讲到哈,这个是哈,根据高低转法来生成ID。数据表删除。安亲没了。Harm,这看。注意这个时候的话呢。断点还是在三十五行找一个。
23:10
大家看到一个什么呀,大家看到我执行了一个查询操作跟更新操作,但是的话呢,并没有这隐色的吧,因为我这个查询和更新实际上是在确定那个ID值,就说这个时候啊,我这个ID已经有值了。但是我并没有执行那个眼色操作。那我直到执行到commit方法,我把这一行往下走的话,才会来真正的发送这个in色语句。回来这个高级,这个高级算法的话呢,我们后边还会来说这块的话呢,我们就不详细来解释它了啊,这就是一个例外说,如果记住这个ID是由底层数据库使用自征的方式生成的,那我在调用调用这个save方法时时。就会立即来发生这个色的语句怎么样,因为只有这样的,因为只有发生in色了,我才能得ID吧,数据库自征吗。
24:11
这是一个例外的情况,也是我们需要注意的。看一下这个flash。Flash。Session按照缓存中对象的属性变化来同步更新数据库啊,默认情况下塞按以下时间点的刷新缓存,第一个显示调用flash方法,第二个调转三声的commit方法,这个会先执行flash操作,我们说这个flash啊。后项数据比较事物。当应用程序执行一些HQL啊C查询的时候呢,如果缓冲终端持久化对象的属性发生变化的话,也会先执行flash操作,以保证我查询的这个结果是最新的flash操作的一个例外情况。
25:01
如果我们使用native生成OID,那么我在执行这个save方法保存的时候呢?它有可能会立即向数据库插入记录以得到。我。我的这个ID。否则我就否则我否则的话,我这个ID得不到是吧。Commit跟flash的区别,Flash会执行一系列的口,但不提交事务,而commit会先调用flash,然后再提交事务,啊我只有commit,那我刚才这个变化的话呢,才会永久的被数据库。保存起来。我们可以通过调用session set mode方法来设定。调用flash的时间点,那这个的话呢,了解一下就可以了,通常情况下的话呢,我们是不用来调用这个方法。回退。我们说的第一个方法叫flash看,第二个方法叫refresh。
26:04
这个箭头啊,是从数据库指向缓存,什么意思啊?它会强制使缓存中的某一个对象的状态跟数据库的记录一致。换句话说,它会强制的去发送一条select语句。测试一下。他。Get on rebr。At test。首先有一条记录。打印一下。
27:02
看一下数据表。记录没问题。好,走一个。这个呢,我们前面已经研究过了啊,没什么说的好了。那我现在呢?再打一遍。他说。我再打一遍这个结果会跟这个有区别吗?当然不会。那我现在呢,我希望四十五行加上一个断点,就是说我希望我在。又一次打印,之前我打印的是这个对象的最新状态,懂这个意思吧?就是说哎,我停的时候啊,我手工来改一下这个字段,然后我们看这个值是不是最新的。Debug。四十五行停住。
28:01
刚才打印的这个结果呢,就是一个select,那确实是啊1JAVA3这没问题哈,好回来。我改一下,把这个改成凹口。保存。我在。执行这个打印操作,下一步大家看是不是进行了一个打印呢,他连SQ语句都没发。所以说打的这个结果跟先前是一模一样的。哎,那么我们这个方法叫refresh,我就是希望。我缓存中的这个数据是一个最新的状态,换句话说,调这个方法的话,它会强制去发送一条。Select语句得到记录的最新状态。看一看是不是这样过吧,这个。回来。于是呢,我在这个之前要一个三点。
29:07
刷新0NEWS啊,我想这个news是一个最新的状态。看一下。Debug。走。前面发的呢,还是什么呀,还是这个select以及这个打印这个没问题哈。我再做一个修改。改成散。保存。回来。那个余乐钱。啊,看了个代码,先下一步大家看。是不是查询了一下呀,哎,起码他查询了一下,那查的这个结果是不是最新的呢。第一把是Java,这里边我已经改成了扇是吧?啊这是Oracle啊,这是Oracle这边我已经改成散了。
30:04
好。下一步打印。哦,这个结果还是奥口。我虽然说查了,但这个结果并不是最新的,这是为什么呀?啊,我们回来这个呢,涉及到另外一个点,但是我们这个refresh实际上已经开始工作了,我们把这个笔记先做一下,后边那个的话呢,我们一会再说。Refresh。会强制。强。发送。Select。伊始。再生缓存。中对象。
31:02
的状态和数据表中对应的。记录保持。无论是不是一致,他都会发,因为他并不知道数据库里面那个记录是什么样的,懂吧,一定会发送这个语句,以使缓存中对象的状态跟数据表中的。状态一模一样。那现在的话呢,我们看刚才那个问题,我已经发语句了,这不是在这儿呢吗?是吧,发语句了,但我查这个结果并不是最新的。这什么问题,这个呢是。嗯,买circle事物的隔离级别问题。看一下PPT。数据库的隔离级别。事物的隔离级别。我们知道。
32:02
嗯,在进行病房操作的时候呢,可能发生脏毒,不可重复读以及混毒,所以说我们有必要对这个事物进行隔离。这个我们在讲这个JBC的时候呢,已经详细的说过了哈。下一页啊,数据库提供了四种隔离级别,分别是。呃,读未提交,读已提交,可重复读跟串行化,Oracle支持两种。读已提交跟全新化or口默认的是读读已提交,买circle呢提供了四种。MYSQL默认的隔离级别是什么呀?叫可重复读,所以说我们刚才看的那个结果,虽然说我已经查了,但是我在这个事物内,我读的这个结果是重复的,还是以前那个结果。那么我们可以显示的来修改my circle的隔离级别。我们可以写这样的命令是吧,在这个MYSQL里面,把MYSQL这个隔离级别给他改掉,那也可以。
33:07
在hamlet里边来设置。隔离级别,那我们看吧。一呢代表读未提交,二呢代表读已提交,四代表可重,呃,这个可重复读。八代表序列化,Harmlet可以通过connection isolation把这个值设置为二。让它变成读已提交设置一下。作者。啊,事务隔离级别。Property collection。AOL。把这个值设置为二。
34:02
1248嘛,是吧。再测试。Debug。这步时我们打这个结果是谁呢?呃,是散。回来。注意哈。我refresh加了一个断点。我改为Oracle。保存。这个时候这个refresh,我为了保证缓存中这个对象是最新的啊,我会发一条。在语句发了看,达到这个结果。是不是改了呀,改成了or口,所以说刚才那个呢,得到这个结果不正确呀,并不是refresh这个方法的问题,而是my circle默认这个事物的隔离级别问题,我们通过设置这样的一个属性。
35:00
就先过哈。把这个问题呢,就可以给他解决掉。好,再回来。这是我们说的第二个方法,叫refresh,还有一个叫clear。格利尔到清理缓存。不是以前啊,这个缓存里边的话呢,是有对象的,我一到可丽尔啥也没有了。叫清理缓存看一下。Public voice taste clear。说吧。列方法。要清理缓存。我们首先获取一个对象news。等于再点that use.plus d。
36:12
再获取一个。这个我们俩前面已经讲过了啊,我通过这样执行的话,他会怎么样。只会发送一条S口语卷吧,对吧,因为有一个session的缓存。我现在在第二次召开的方法之前使这个塞身。要一个列方法缓冲清了懂吧,所以说你缓冲清了,我发现缓冲里面没有这个对象了,于是我还需要再查一遍。哎。两条色口,这叫清理缓存。OK,那以上的话呢,就是我们讲的关于操作塞身缓存的三个方法。
我来说两句