00:00
来,接着来看啊。我们刚刚讲的是这个过滤器的它的一个基础知识啊,相对还是非常简单的,那下面呢,我们再来看它的一个应用。关于我们的事务管理的一个应用,那这个知识点呢,比较的比较的晦涩难懂啊,大家要要要坚持听一下。来,同学们一起来看我屏幕啊。我们在JDBC部分,在GDBGBJDBC部分啊,我们可以去做我们的事务的管理。好,我们来给大家画个图啊。是这样的。我们的客户端。然后呢,这是我们的服务器端。这是我们的服务器端啊。那一个请求发过来,首先呢,它会经过我们的。会经过我们的这个叫。好,所以呢,我们可以画一个组件。
01:00
这是我们的。或者叫CTR都可以啊,这个名字无所谓,CTRL。然后呢,这个controller呢,它会去调用我们的service层的方法,所以这是我们的service。所以我们在这边写个service。那行。然后呢,Service呢,会去调用N,会去调用N多个DA方法是吧,同学们。他会去调用多个DA方法。所以我这边我就写个DA1或者叫零幺啊都可以。DAO01。好,它执行它里面的一个方法,那么这一个业务功能会有多个DA方法的组合,才能完成这一个业务功能,这个没问题吧。行,所以我这边我再写个do。D0,二。我们写一下DAO02。
02:01
再来,我们再来写一个DAO03,咱们要不就写三个。DAO03行吧,就这样吧。好,他会经过他。那么这一个service方法,这个service方法它的内部。啊,我们要定它。定他。然后再调用它。啊,会用这三个do。第一个DA当中,我们的步骤大概是什么样子的呢?在第一个DA当中,我们的步骤大概是这个样子的。第一步。获取连接。设置啊,或者叫获取连接。取消自动提交取消自动提交。
03:05
好,然后呢执行操作。执行完操作之后呢,我们要去叫提交事务。啊,手动的提交数。那么我们在执行操作的时候,我们在第二步这边我们要做个TRY。然后在这个位置我们做个catch。Catch。如果捕获到异常了。如果捕获到异常了,我们要在这里面要做回滚。是吧,同学们,这是我们的一个步骤。获取连接,取消自动连接啊,或者叫开启事物都可以。这个取消自动提交,这个是什么呢?叫connection.set auto commit。Auto commit commit提交嘛,把它改成false是吧,同学们这个API我在前面给他提过一点点。我们补充讲的那个叫事务管理嘛,事务我们首先讲的是事物的概念,然后简单看了一下JBC里面的操作啊,取消自动提交叫connection.set auto commit。
04:06
我们把它改成for。然后呢,我们提交事物是什么呢?是不是就是connection点呀。就这样子,那我们回滚事物是什么呢?哦,我们回滚事物就是connection.back。这就叫回滚。行啊,我们把这个操作稍等一下啊。把它放到这儿。然后这样我就可以把它往后面挪一点啊。好,没问题。就这样的,我们用一个框框把它框起来啊。用蓝色的框把它框起来。这是一整块儿。那么这一一整块应该对应的是do当中的某一个操作没问题吧?对应的应该是他。那请大家想一想,DA02是不是下面也应该有这一整套的操作。DAO03里面是不是也有一这一整套的操作。
05:00
OK。所以呢。所以呢,我就把这一整块。我就把它拷贝一份。回到这边来。啊,我们把它拷贝一份。就这样吧。啊,不能剪切啊。怎么能剪切呢?复制一下就可以了。好,就这样。复制一下。Could you see you,再把它拷过来放在这。没问题。把它放在这啊。把门关一下啊。大家把门关一下。然后这个呢,我把它画一下啊,我就用这个线把它画一下。所以这是我们这个方法。他执行的。那行。那么第三个。第三个do是不是也有这个操作。好。那这都是没有问题的啊。
06:00
那现在呢?我需要问大家一句话。好,我就画在最下面。我们的service。Service中。当前。当前service中包含了三个do操作。是吧,三个地操作。那么。啊,之前的叫do的事务管理的啊,事务管理的基本API。啊是右边写的写的方式。这样的方式带来的问题。带来的问题是?有可能比如说啊带来问题,带来的问题是什么呢。DA01。执行成功。DO02中的操作执行失败。啊,那么会回滚。这个DO01执行成功,那么他会提交。
07:01
然后呢,DA03执行成功,那么他也会提交。那这样。啊,这样的问题是什么呢,这样。其实。Service。操作是成功还是失败?我问一下大家。不是也成功了吗?按道理来说,我们这个设备操作,你应该是三个都给我执行成功吗。结果你里面俩成功,一个失败。那我这你不能说有部分成功部分失败,这个不符合咱们那个业务操作这个规则。啊,转账的功能。两个人转账,一个人扣款。啊,一个人账户增加钱,你不能说一半成功,扣款成功,那个增加钱的那部分失败。这是肯定是不行的是吧,一半成功一半失败,这肯定不行的。大家能听懂吗?嗯。啊,所以我想告诉大家的是什么呢?
08:00
我们的事务管理的操作,我们不能够写在DA层。啊,四位子。啊的操作。应该是一个整体。不能部分成功。部分失败。比如。比如两个人完成转账。转账的操作。啊,两个人完成转账的操作。啊甲或者叫张三啊,张三客管。成功。成功了对吧,李四啊账户。账户增加金额。增加金额失败了。啊,这个肯定是不允许出现的。是吧,同学们肯定是不行的。啊,因此。
09:01
Service是一个整体。要么都成功。要么都失败。所以得出结论。啊,我们就得出个结论。我们的事务管理不能以。啊,不能以do层的单精度方法。方法啊,事务管理不能以do层的单进度方法为单位。而应该以。业务层的方法为,单位。大家想想是不是?啊,应该是以他为单位的。行,咱们下面的这个应该也有啊,要不以防万一把它往上挪一点。好,这就是我们所写的内容。OK。我们当前service当中,你看又包含了三个do操作。
10:02
啊,你不能说一半成功一半失败,那肯定不行的。所以呀,咱们回到这个图。我们把它保存一下啊,第三个。我们就不能把这个事物的管理操作,我们就把不能把它塞到do里面去了,这肯定是不行的。我们需要在service层。我们需要去使用事物。那我们应该怎么做呢?我们应该怎么做呢?来,我们把这个图再来重新画一下。我们再来画一张图啊。好,这是客户端。这是我们的服务器端。然后呢,这是我们的。把它画在这。这是我们的。
11:03
好,再往下,这是我们的service。Service。再往下,我们有do。那我们有三个点。好,这是do。好,再来,这是DA2。再把它画在这。好,再来DO3。好,差不多就行了啊。BO3。行。所以呢,我们的事务操作,我应该是在这个service上面的。好,把它画在这。我们应该在四位子。上面。稍等啊。我应该在这个位置。
12:02
画一根线啊。好,这边咱们也画一根线。差不多。我们应该在这个位置开启。叫开启书。啊,其实就是我们设置事务不自动提交是不是啊。然后我们在这边TRY。TRY是不是把我们中间的service这个业务方法把它包含进去啊?好,然后在这个位置咱们开启。OK。稍等啊。把它开刀。一旦我们开启到。一旦我们开启了,我们在这边,我们要回滚。啊,要入back我就写个back,写伪代码行不行?同学们,我就直接写个back啊。
13:01
那么在这边我们要去提交。提交。好,就是这样的。OK。差不多啊。应该能看得懂这个图吧,我们开启15,然后TRY执行service里面的操作,执行完之后进行commit,那么执行操作和commit,我们要用try catch把它包裹住。一旦你出问题了,我们要进行入是吧,就是这样的。那么请问一下这一个service操作,这一个service操作,它是不是就包含了咱们三个do操作的这个。三个do的方法呀。啊,执行它。指引他。指引他。没问题吧,同学们,我们应该是这样的。大家先不要管代码怎么写,这个图应该是能看懂的吧?
14:17
那么其实啊,我们可以把什么呢?我们这边一个请求发过来给去调用service里面的方法,那这个service方法我们要执行啊,开启呀,提交呀,回滚呀。我们可以怎么做呢?我直接把这个事务管理的这一系列的操作听好了啊,我会把它前置。我们再重新来画个图。这是我们的客户端。这是我们的服务器。这是我们的一个。后面是我们的service。后面是我爹,稍等啊,太浪费时间了。
15:04
拷贝啊。零五。零三把后面的删掉。好,编辑一下。来,我直接把这个开启啊,提交呀,回滚呀,你看我怎么做。我现在呢?看好了啊。我现在呢,把这一块。稍等啊。稍等一下啊,Ctrl c c you v。我把这个里面的内容我稍微修改一下,把这边删掉。把这边也删掉。然后呢,我把这边的代码你看好了,同学们,我把这边的代码。剪切。我把它放到这,嗯,这个还一点。这样吧。剪切。放在这。啊,把它放在这。下面这个内容。剪切,把它放在下面。
16:04
把它放到这。没问题,把它放到这。好了。那么后面这个我就不要了。后面这些就不要了,删掉。Service就是正常的service。把它删掉,这边把它删掉行吧,同学们他就正常的。OK,没问题啊,他就执行他。好,Service报do,那老师你画的这画的啥,这边是啥呢。好了,这边我们需要一个组件。哎,这个组件就是我们的filter。啊,就是我们的filter。我们filter里面所执行的代码,就是我们这边所谓的事务管理的操作。我们在这个filter里面稍等一下啊,这个代码我也可以把它删掉。
17:00
重新写一遍,无所谓啊。无所谓,这个我把它画的大一点。这个我们称之为叫。Open session in view future。啊,叫open筛选in view filter。他里面做的事情是什么呢?它里面写的代码是这样的。首先,TRY。开启代码和我们刚才其实是一样的。Exception。在这里面。好,我们在这个地方。首先第一步啊,我们执行set auto commit。False,行吧,同学们首先执行它。
18:01
这个要不改成auto commit啊,改成false。就这样吧啊,字看不见无所谓了啊,第二步。我们要放心。啊,要放行。然后。在这个地方我们要执行commit是不是啊。一旦出问题,我们就入back。这是我们filter它当中的代码。就是这样的。那大家想想,你一个请求发过来的时候,是不是会被这个过滤器给拦截啊。拦截下来之后,它是不是要执行O叫set auto commit force,然后放行,然后就执行,就调用service service,然后再去用do里面的方法呀。第一个方法,一旦这里面任何一个方法出问题,是不是都会被开启到。开启了,我们就入。能看得懂吗?因为你后面所有的这些操作是不是都都包含在放行这一句代码里面了。
19:04
能听懂吗?同学们就是这样的。这就是我们一个过滤器的一个比较典型的应用。希望大家对这个图要能够理解,不要管代码怎么写,不要管代码怎么写,先把这个图要能够理解了。那么图例理解之后,下面我们就要跑到代码里面去了。我们代码上应该怎么实现呢?同学们,如果我改成这样。其实我们想解决的一个问题就是这三个DA他们要处于同一个数。好,当前当前的难点。难点。DOE。DOR。DAO3。这。啊,这三个组件中的三个操作。
20:00
三个操作。需要同一个connection。这样我们才可以。这样我们才可以让三个操作。啊,处于一个事物中。啊,除以一个食物中。很容易理解啊,你这边不是有connection.set auto吗?那你这个点connection到底是谁啊?到底是DA里面的connection,还是DA2里面的connection,还是DA3里面的connection?是吧?同学们,你不是有个叫connection点吗?你不是还有connection点吗?不是还有connection点吗?那你说connection到底是指的是谁?是CONNECTION12还是三?你如果直接一,那是不是二和三就和这边没啥关系了。所以我们应该是这个connection是三个里面的connection,那也就意味着三个方法里面的connection是同一个。
21:01
这就是我们当前所碰到的一个难点,那么我们如何才能够让三个方法里面的connection是同一个呢?如果用我们面向对象的方法来做的话,我们得传参。我们需要传参数,在第层的方法上面进行传参数,第一个方法connection用完了。啊,我service service层我需要调用第二个do的方法的时候,这个方法的参数里面必须得带一个connection。什么意思?我们的方法签名必须得改成这个样子。第一层假设啊。一个方法叫艾零幺,这个方法。我正常情况下,我里面写的是fruit。现在不得不在后面再带一个。啊,方法签名就变成这个样子了,那这个签名多丑啊。DO02也是一样的,假设我这边有update啊,假设叫update,或者或者叫update order,随便瞎写一个吧,啊,叫update order。那我这边假设一个O的。
22:01
那你后面是不是也要带个啊。那你想一想。我们这个单精度方法,你这个connection是不是具体的实现技术上的这个这个类啊,或者叫接口啊。是吧,那你这个总带一个太丑了,你只有通过方法参数签名的方式,是不是才能够才能够达到connection用同一个进行传递的这个目的啊。而且你在第一个里面connection不能关,在第二个里面connection不能关,你在第三个里面最好也不要关,我们可以在这个地方进行关掉。啊,这是我们使用面向对象的方式来进行来进行处理的啊,这样的方式稍微有一点点小的麻烦。好,那我们怎么来解决呢?我需要来画下面一张图。再来看。好,我们举一个生活的案例,这是一个工厂。这是一个工厂。啊,这个工厂有三个员工,这是第一个员工。随便意思一下啊,就画在这。
23:02
这是第一个员工。OK。啊,这个工厂有三个员工。这是第二个员工。这是第三个员工。就这样吧。那么这三个员工呢?在这工厂里面干活。按道理来说。你这个企业应该给三个员工一人发一套工具嘛,这是最基本的嘛,你没有工具人家怎么干活呢?那咱们这个企业为了节约成本。工具只买了一套。他只买了一套工具。然后让这三个人怎么工作呢?哎,这三个人请你们并排坐,他在这个桌子上,他安装了一个,大家有吃过旋转小火锅吗?没吃过吗?没吃过大家,我就给大家一个机会,让大家认识一下什么叫旋转小火锅啊,中午可以请我吃饭是吧?我们去吃旋转小火锅。啊,他在这个工作这个桌面上,它装了一个这个可以能够自动的转转动的。
24:01
这么一个纽带。啊,他装了这么一个东西好。我们在这边画一下。啊,也就是说我在上面装了一个纽带。这个纽带可以转到。然后呢,这个老板呢,他就把这个工具箱。啊,这是我们的一个工具箱。他放在这边。那第一个用户他可以拿拿下来进行使用,使用完之后他再把这个工具再放了上去,然后咱们这个工具纽带是一直往前滚动的。啊,我们是一直往前滚动的,把它画在这。所以说呢,它呢,所以说这个这个工具工具箱呢,又会随着这个纽带滚动,滚动到下一个。啊优会滚动的下一个。又会跑到这儿。就这样子。所以第二个人又把它取下来。进行使用,使用完之后再放上去。那么这个工作的纽带再继续往前滚动。
25:03
啊,这样呢,我们第三个人,哎,又滚动了第三个人的边,第三个人再接着使用。使用完之后再放上去,然后再回来啊,第一个人又可以用等等等等,就这样。那现在这个滚动的这个纽带是什么呢?当然这个例子举得不是完全和咱们的程序完全这个,呃,概念上完全精确的匹配啊,这个没办法啊,但是咱们咱们可以通过这个来理解,我们把这个纽带我们就称之为叫local。啊,这个类叫ad。啊,我们这个翻译过来叫本地,所谓的叫本地线程。我们怎么能够完成三个人,他们使用的是同一个呢?我们使用我们的线程ID。一致就可以了。啊,同一个线程嘛,线程ID一致啊,这样就可以了。它具体的底层原理,大家先不用去,不用去管它。啊,现在我们先搞懂它是怎么去使用的。
26:00
瑞的logo。那么这个lock呢,它里面有两个方法。第一个方法叫set。我们可以把一个对象,比如说connection。Set connection,我们把connection对象通过set方法设置到当前的这个logo里面去。那么第一个人可以使用。那么第二个人我可以去调用一下get方法。调用一下我们log它的一个get方法,调用get方法既能够取到它set进去的这个connect对象了。就这样的,大家只需要关注于这两个方法就可以了。那下面咱们就开始要进行编码了,概念啊,我们基本上就已经全部把它说完了,保存一下。
我来说两句