00:00
那么我们讲完这个local的一个事例之后啊,我们来看看使用future和来组合管理这个事。首先呢,我们先来看一下啊,为什么有必要来组合管理这个事哈,我们把这个书城跑起来。苏城跑起来。稍等啊。好,那么大家注意看一下哈,等它跑起来哈。啊,启动了。那么启动我们来访问一下。这个是book啊,咱们叫book。好,这个启动了,来咱们看一下哈,咱们来看一下购物车这个地方。结账,他让我们登录我的命,我的命没问题,现在我打开数据库,这个W0的数据库。
01:02
干什么事情呢?呃,我打开。这些数据啊,我打开这些数据都删了,都删了订单和订单项把。前面实验的数据都删了哈,那接下来我们看看这里。我们到购物车里面去结账的时候,大家看这是不是生成了,呃,数据库呢,一次把订单。对吧,D单项都生成了,同时还修改了什么东西,还记得吗。把这个关了啊,同时咱们还修改了库存和销量,对吧,咱们昨天最后做的嘛。好,注意看一下这里呢,还修改了库存和销量,而且呢还保存了订单和订单项,那么我们知道当我们这个结账的时候啊,这些操作是需要什么一次性全部成功的,那如果说我们在操作的过程当中,中间如果有一个错误阻截了这个所有操作的全部成功怎么办?
02:06
这时候这时候注意看啊,我再重新部署一次。我让这个错误啊,这个错误呢生效,我们看它会是什么效果。好,现在它重启了,大家注意看一下哈,我把这个内容。删了。然后订单也删了,好大家请看一下啊,那这个时候。呃,我们再去买点东西。啊,再去购物车结账,才让我们登录,我me,我me好,这时候请看啊,那如果说我点击购物车,我点击结账,大家看一片空白,因为什么?因为服务器这边已经报了错误,是不是除以零,这个时候大家注意看结账那个操作在数据库当中,我们先看这个订单,订单是不是保存成功了,因为这个错误它是在。
03:00
保存订单之后的,那其他的操作呢?你看订单项是不是啥也看不到,你说这个时候人家钱也付了,你只看见一个订单,而店家想发货的时候,居然不知道谁能买了什么,你说怎么发货?对吧,这个钱平白无故的凭空进账,这个算不出来从哪来的,这个时候就很有问题了,这时候怎么办呢?大家注意,我们希望订单订单项以及图书的这些销量库存的修改啊,是一次性成功啊,要么就都失败。那么这就需要用到什么,这就需要用到我们基础讲的数据库的事物,哎,事物好所咱们了解一下哈,既然要用到事物,我们就先来回顾一下,咱们基础讲了这个数据库的事物到底是个啥样子,来回顾一下哈,回顾啊,JDBC的数据库数管理大概是怎么做的?首先得有一个连接对象,GDBCU调试点get。
04:08
Connection这里是得到连接,得到连接以后大家想想哈,我们在这里是干嘛?Try catch捕获这个异常是吧?捕获异常大家看这里面怎么写啊,1234首先连接要设置为凹凸,Commit等于false这啥意思?设置为手动管理数。设置为手动管理术,完了以后你要干什么事情呢?执行一系列的GDBC操作,没错吧,如果中间没有任何的异常怎么办呢?connection.commit手动提交书,手动提交事,就这样子,哎,那如果说有异常呢?
05:07
楼。Back,这里是回滚数,就回滚数好了,这个呢,就是咱们基础那时候学习GDP的时候讲的事务管理对吧,那么从这个事务管理当中,我们要知道一个点就是什么东西,大家注意看一下哈,那么要确保所有。操作要么都成功,要么都失败,就必须要使用数据库的事务。那么要确保。要确保,大家注意哈,所有操作要确保这个什么呢?所有操作都在一个事物内,就必须要什么确保所有操作都使用同一个connection连接对象,这没错吧,哎,这个是我们这个先决条件啊,你要让他们要么都成功,要么都失败,那么他们必须是用一个数,要确保一个事,就必须确保他们所有操作都用一个连接,那么我们如何?问题就来了哈,那如何如何确保?
06:30
所有操作都使用,所有操作都使用同一个,肯定是连接对象呢,这就是问题了。这就是问题了,好,我们来看一下怎么做呀,谁能解决这个问题。谁能呢?就是我们刚刚讲的local,它可以还记得我们演示吗?我们用local大家看一下哈,往这里面存了一个数据,我们在当前线程内取的时候,随时是不是都能取出来,都能取出之前保存的数据,那么我们这个地方也一样啊,如何确保使用同一个可能省离线对象呢?我们可以使用select local对象来确保所有操作都使用同一个connection连接对象,他能是吧?呃,他能,那么大家注意哈。
07:29
这个水口。他要确保使用同一个连接对象,它也是有前提条件的。什么前提条件?注意一下,Local要确保所有操作都使用同一个连接对象,那么操作的前提条件是是什么?是什么?大家注意了哈,来。
08:03
所有操作都必须在同在同一个线程中完成,这个一定要注意,那么我们在前面也是这个16LOG的时候,咱们是诶哪呢。这边咱们在演示这是这样的是吧,它只能为当前线程绑定一个数据,那么其他线程再使用的时候,那就是另一个数据了,那就不是同一个connection连接对象了,是吧?诶那我们就先来看一看。先来看看我们的这个。生成订单,所有的代码是不是都在同一个系统中完成?我们怎么看呢,很简单呢,打印这个当前线程名就可以了,来请看啊。我们在,呃,订单这个地方。我们。在这样一个位置,哪,在这个位置我们打印一下当前线程里啊,咱们说O的程序。
09:09
在什么什么线程中。跟面啊,这线程名是吧,在线程中好注意看啊,我在所有的代码里面都打印这句话啊,看看哈,先是在什么啊order,然后到这个这里面哈,这里面我们找找一个一个来。到service的,我们也打印这行代码,这个地方咱们换一下。换成all service input,诶复制多了all service input,哎,完了以后大家看我把这个代码呢,再复制到它下面用的每一个do当中,是吧,但我得先把这个错误去掉啊,它它才能够顺利执行完,那还有这个。
10:01
呃,O的deal,我们也找找吧。O的DA就这里面走,大家看一下哈,那么这是它OK,我们把这个代码甚至放到贝斯do的update里面去来是吧,我我在所有地方我都给你打印嘛,我看你能跑到哪里去是吧,贝斯do。好,别着急哈。来,我要复制那O的deal,咱们弄完了看到谁了,到O的item deal就是这里面。我们每个里面都写哈。嗯。还有谁呀?呃,Book do的update,更新图书嘛,更新库存销量嘛,是吧?呃,我把它也拿过来。好,现在呢,我们所有跟生成订单的这个代码呀,我们都打印了这个什么当前线程名,我们来看看他们的线程名是否一致啊,是否一致现在啊。
11:07
我确认一下这个异常给他做的哈,来再次启动,我们再测一下这个生成订单,我们就看。它的这个线程是不是一致。啊,稍等啊,他在那启动。嗯。好,启动成功,正在启动哈,来我加点东西,呃,去购物车结账的话,它让我登录,让我登录orderin orderin好,别着急。啊,现在去购物车,大家注意哈,我先把这边清了,咱们一会儿看现场打印。结账他跳过来了,我们就看看这个线程名是不是一致。大家看一下8080,呃,EX1C Excel c是吧,一一,你看下吧,这性能名是不是一致啊。看见吗?完全一样啊,哪个都完全一样,大家可以自己看看,完全一致好了,那也就是说我们要使用select local来确保所有操作都用同一个connection对象的前提条件咱们就有了。
12:13
是吧,那有了以后怎么样呢?咱们就可以用了,那大概怎么用来我给你分析哈,也就是在上面这样一个位置。再占个位置哈。咱们要先有select local对象,好等于new local,然后。这个地方有一个连接对象对吧,我算的这个local嘛,然后这里是不是获取这个连接啊,获取连接的时候怎么办呢?大家注意看一下,我在这里面set好,我把这个连接对象放进来。这是干嘛,咱们说一下哈,呃,换个色稍微明显一点吧,咱们说保存从数据库连接池中获取,获取到连接对象,哎,咱们就获取到了。
13:14
咱们就获取它了,就这个。好,你从这边就放到放到这边来。好,那你下面大家想想哈,你下面所有的操作是不是都用上面这个连接对象。没错吧,好,那么这个地方。大家看一下,我在这里面connection是点get,诶得到前面保存的connection连接对象没错吧,好,这时候他从哪来的呀。大家请看哈,你这些操作,这些操作都是从这边来看见了吗。我去取呀,你上面不是保存了吗?保存我取呀,然后再来看哈,咱们中间有一系列的GDP套错是什么东西,咱们可以理解为。
14:03
注意看order service.create order是这样吧,这里面这里面分别是谁跟谁呀?请看着哈,这里面无非就三个操作嘛。三个操作嘛,咱们再往上一点点啊,分别是谁呀,就是O的do.co的。是吧?别着急啊,我给你写写啊,换成黑色吧,有点写不下来,还有什么all的item do.safe的item,无非就这样吧,是吧,还有什么book do.update book不就是这样吗?你想想哈,好,现在。我这里面这三个操作,我要用同一个连接怎么办啊怎么办,那也很简单,没有那么复杂,你看啊,我把这个操作。
15:00
我换个伞。呃,我把这些三个操作都怎么办呢?从这边来获取,怎么获取,我还是调用它这个代码看到了吗。还是通过这个connection get里面,那我得到的是不是还是前面保存的一个连接对象啊,哎,还是一样。还是一样,那么你想想哈,那我这个事物提交和回滚呢,我这个事物提交和回滚呢,我也依然让他什么使用。这边这个。能能理解吗?我还是使用它,哎,当然了,咱们上面这个操作其实还少个东西,少了什么,咱们是不是应该关闭连接啊,这还需要关闭连接哈,那么final我关一下。好,呃,这个final啊,咱们就换成黑色啊。好,那这里面得怎么办呢?稍等我我移一下。
16:00
好,大家注意看啊,这里要关闭连接的话就是GDBC u.close好,这里面是什么?这里面是不是肯定是连的对象啊?好,别着急,那么我关闭连接的时候,我能随便关吗?也不能。也是怎么样,大家请看,也是同样要到这边来,我是不是获取我前面操作那个连接,那我怎么去获取,还是通过它,大家看懂了吗?看懂了吗?这样子的话,我们就可以使用这个local,让这些所有的代码从始至终都使用同一个connection连接对象了,对吧?好,那么我们分析是分析,但是具体的代码要怎么改,来请看。那么我们得从获取连接这个地方开始改吧,对吧?那获取连接是什么?是不是GDBCU里面呢?来这一栋的改了就大了。
17:00
我们把这些都关了哈,呃,我们找到这个工具类。呃,U条gdbc u条呃,大家看哈,在这个地方,咱们现在上面创建一个local啊,Private static select local保存的数据是什么?连接等于6LOCAL,好,每个都是连接。是吧,每个都是连接好了。OK,然后呢,我我们可以干嘛,大家请看哈,我们在这里面获取连接的时候啊,咱们就是呃,Connections这都得改哈,不是这么写了。Connection connection等于那或者是你直接就等于叫叫做connection是点get它,那么这里呢,要判断一下,大家要明白一个点就是什么,就是我们第一次从里面取的钱没保存以前,那么这个地方这个值是什么,是不是等于空,能理解吗?
18:08
哎,就会等于空,那么如果它等于空怎么办呢?我们这个连接就从数据库连接池里面去。我们就从连接池里面去。好。那么大家请看哈,看这边我们对照着来,这边获取完之后是不是放进来啊,注意看,那么我先我先停了哈。写到哪了啊,行啊,不是是上面。来大家看啊,我获取完之后,我保存进去以后,你们就有了吗?connections.set连接,我们说保存到所在的logo对象中啊,那么供后面的GDBC操作使用,对吧?同时再来看我们这个设置为手动管理数是什么,是不是从这里面取的。
19:02
好,那么我们取连接的时候啊,就就拿这个链接,我直接注意看啊。点set out to commit,我直接设置为手动管理,能理解吗?我直接设置了,哎,那么所有的操作完了以后,我们在这个地方连接。好,大家看这当然我们就改了哈,就改成这个样子,我稍微去掉一些行,因为咱们屏幕小,放不了那么多空行啊,就不考虑美观了好。大家请看这是什么?从数据库连接池中获取连接啊,就这样子,咱们就先从这里面取是吧?如果说你前面没用过,那就咱们从连接池里面取,取了以后放进去,然后再设置为手动管理,那想想如果说你后面的操作还用,就举个例子说,比如说我DA里还需要用,我这怎么办?我从肯定里面取,我还是调用这个方法,但是我这时候取是不是有值了,能理解吗?我第二次取它就有值了,那我就不需要再从连接池里面取,那这不就确保了我同一个连接吗?
20:11
对吧?好,那么除此以外,大家注意,我们要使用show还需要有commit low back,对吧?哎,Commit,那么大家注意哈,不管你是提交事还是回滚数之后,他是不是都需要。关闭连接。都需要他好。那么我们,呃,简单一点,偷个小懒,我们把这个提交和关闭放在一起,因为他们两个都一定要操作的是吧,那么回滚和关闭也都放一起啊,都放一起操作啊,因为因为什么呀,不管你是提交还是回滚,你的这个连接肯定要结束吧,事务结束连接就得关闭哈,所以把它们组合到一起来写简单一点。那这个代码展示就不用了啊,那变成什么东西呢?我们需要加两个public static,叫做commit and close。
21:08
啊来,我们说这什么东西呢?提交事并关闭释放连接。那下面就还应该有一个什么,有有提交的就应该有什么。是不是回滚呢?Low back,这是回滚数,好回滚数,但是大家注意看到啊,我们提交的链接从哪来?你请看上面这边,你提交是不是需要从connection里面得到这个连接,对吧?那我的界面就这样子啊,connections.get我得到连接对象。那么我要先判断一下,说如果这个连接不等于空好,就说明什么,说明以前用过,如果不等于,那说明之前啊,那么使用过连接,操作过数据库,就这样子好,那既然他操作过,注意看啊connection。
22:16
啊,connection.com这是什么东西啊,提交数吧,哎,同时连接还要关闭啊,连接还要关闭。关闭连接释放字眼是吧?好,我把它们都捕获一下,他们他有异常啊。啊,就这样子啊,就这样子,那这个代码呢,你如果想写的再严谨一点的话啊,其实你你在这个地方你可以把它。把它剪切出来是吧,就是不管你那个操作成与不成,我都要换连接,那么我在这里再呃拆开一下,这样可能就更严谨一点,哎,就这样子。
23:03
啊,就这样子好,这是提交数,那么这个地方注意一点啊,用完之后。一定要remove这地方一定要注意啊,一定要执行remove操作,否则。就会出错,记住啊,嗯,括弧因为什么呀,因为come on cat呃,服务器底层使用了线程池,记住啊,哎,那你这里必须要移除的,不移除是不行的哈,那把这个复制过来,大家注意提交是这样子,其实回滚呢也差不多,无非就是把这个换成回滚而已,就就完了啊。回滚术完了。咱在这两个方法大家看啊,我这些方法一旦加上,那么我们事务管理当中所有的这些操作咱们就都有了。
24:07
那剩下的就是。在DAO里面获取连接的时候,这个地方咱们要改改。怎么改,请看。啊。呃,咱们这里你看有好的代码就出错了吧,咱们先看看。啊,这个就住掉了哈,这方法咱们已经取消了,就先住了吧。好,然后在这个base DA里面呢,每一个获取连接的地方都得改,你看啊都得改,首先连接关闭了是吧,咱们不能有了,为什么不能有了呢?它不能关呢?我把这个说明一下,大家想想哈,如果说我在DAO里面执行一次,我就把连接给关了,我在这里关了。那么请问后面两个操作还能得到连接吗?不能吧,所以注意DAO当中所有的操作都不能够再宽连接,这个连接必须是在事物提交或者回滚的时候才能关闭是吧?那也就是说我们DA里面这个关闭连接的操作现在都不能有了。
25:12
对吧,呃,以前是以前,现在不行了,都得把它取消掉。好。好,除此以外,咱们这里面还要改什么?还要改什么,大家请看哦。这个地方。是不是把衣裳给捕获到了?你看每一个是不是都捕获到?都不回道,看见了吗?东哥老师,这有啥问题啊,我补货不正正常吗?有问题我补货。不正常吗?但是你想想哈,我我们这里是哪里,是DA里面,如果说我们在safe order的时候出了异常,我们自己捕获了,请问货后面这两个人知道吗?这个地方能捕获到异常吗?他捕获不到异常,我这里能有效的回滚吗?
26:00
不能。所以要注意什么,DA当中有异常,一定要往外抛,把这个异常抛到外面来,别人捕获到最后好回滚数一定要记住啊,就是你可以补货,但你一定要往外抛啊,这个一定要注意啊,所以这里我们也要改怎么做,全部往外抛。乱唱session,哎,把这个放进来大家看一下哈,我们就溜了往回抛啊,这个返回咱们就不要了啊。好,都改成这个样子哈,我复制全部改。全部改。OK。全部改好,改好了以后啊,我们就确保这些所有的操作都在同一个零件里了,为啥你看这个get connection每次获取于它是不是先从的logo中取啊,看见了吗?先从这里面取,那这里不就是以前保存了吗?
27:04
好,那接着就是接着就是追,我们要对这个。All service的这个方法进行try catch操作,那这个方法是在哪里调用的?都有同学说了在里面,所以我们要去supply里面对它进行try catch,请看啊,呃,我们找到。All the里面对这个进行try catch操作啊,在这里呢,确保这个事来吧,我们看看怎么做啊。走,Try catch。好,大家请看哈,我们在它的下面,在这个操作的下面看见哈,它这个操作的下面如果没有异常,咱们提交有异常回滚啊,那么没有异常,GDBCU us.com and close提交数,那么如如果有异常呢?啊,Gd bc us AAA gd bc u是点。
28:11
Low bag and close,看见了吗?这里就回滚数,哎,好,那么我在这里打上断点,咱们来看看这个效果哈,并且呢,我我把这个异常给它加上,把这个异常给它加上,我们看看这个事务管理是不是可以用好啊,那现在呢,我们debug启动一下,同时我们把数据库当中这些数据啊都删掉,我们就看看它一伙是不是要么都成功,要么都失败。好,数据库咱们已经数据库咱们已经清除完毕啊,这个服务器启动了,也启动好了,咱们来测一下啊,走走我们家了,先登录吧,好,然后呢,返回我们去购物车里面,我们现在结账大家看啊,结账这里已经有异常了哈,我们清掉再来这边确认一下没有吧。
29:15
没有没有啊,来激动人心的时刻就要到了,这个事物能不能成功,请看走。过来了吗?过来以后啊。咱们看一下哈,先走往下走进去,走进来之后走打印啊,再走走走这张地方保存订单了吧,已经保存到数据库了,但是由于我们使用了事。所以看这个地方订单里面生效了吗?是不是还没有生效,因为什么咱们还没有提交啊,那紧跟着注意看这里有异常,它就会抛到哪里啊,它就会抛到这样一个位置。啊,就会抛到这样一个位置,请看啊,咱们往下一走,异常是不是抛出了,看见了吗?这里就会干嘛回滚异常请看啊,从这里面得到连接,这个连接就是之前用的那个连接,呃,再看不等于空low back。
30:12
这是不是回滚了,回滚之后关闭连接。看见了吗?这个操作执行完之后,请看数据库。是不是没有订单里面是不是也没有,那是不是就得到了我们想要的,要么都成功,要么都失败,这样一个效果好。
我来说两句