00:00
啊。好,咱们接口已经抽出来了,然后这个第四个版本呢,我们要控制事物,控制事物首先我们分析啊,分析一个问题,事物应该在哪一层控制。事物应该在哪个类中控制呢?这个得好好想想了啊。啊,这么多类是吧,嗯,肯定不是这个吧,排除啊,怎么行吧,这是个病啊,这里边是不是没做什么事啊,啊,所以这个不是它行过了啊。这个这是在这控制事物吗?这是个工具类啊,那肯定不在这控制吧,所以任务呢,就落在这里这么几个类上面的serve service。
01:06
和到那到接口跟service接口你就不用考虑了,那就是一个是什么service,一个是到吧,那我如果让你选的话,你在哪在哪在哪比较合适啊。控制事物啊,事物应该在哪个类中控制?有的同学说是到,有的同学说是survey啊,那为什么没有人同学没有同学说呢。这我就很疑惑了是吧?那没有人说surprise啊,有人说这这个到和service,你看啊,咱们班里边有说到的,说到的我解释一下他为什么说到,我都知道心里怎么想的。为啥呢,你就觉得呀,道里边有连接对象。是吧,那个连接对象它要是存在的话,它是不是通过这个连接对象调一个方法叫set,什么auto commit呀,那个方法是不是开启事物啊,连有了连接对是不是才能提交,有了联系对象是不是才能回滚,所以你就会想了啊,那肯定是在道里边控制,那不在这控制,那没有没没有没有可以控制的呀,对吧,你看这个里边不是有那个零对象吗?是吧,就在这吗?是吧,你会觉得在这开是吧?啊DP求填什么begin是吧?啊是这意思吧,开是物是吧,然后到到到到这到这到这就提交是吗?啊是不是不到这就提交,你就在这提交好吗?
02:30
所以这个东西呢,其实啊,怎么去学这个东西呢,怎么去分析呢,你好好分析一下事物,我们曾经下过一个定义,什么叫事物,事物是最小的不可再分的一个工作单元。一个事物会对应一个完整的业务吧,那我问你啊,这个道里边这个方法执行结束之后是一个业务完成了吗?这个到里边这个update方法执行结束,只要执行一次update这个事就做完了吗?
03:01
我们说过什么叫事无。事物是批量的,什么语句DML语句共同联合起来是吧,完成一件事对吧?这叫事物吧,一个事物是不是对应一个完整的业务啊,那我问你啊,这个业务这这这一条语句是不是完成不了啊。就就就就就银行转账嘛,银行转账就就就执行这么一个啊update语句能完成事儿吗?完成不了了,好了啊,凡是说到的同学们听清楚了,你的说法是不正确的,这是你就是说前两个都对,但是你说这个就错。为什么呢?那我问你啊,你在这拿到连接了是吧,你在这是开启事物了吧,你是不是在这开启事物了,开事了之后你的意思是是不是在这BB点什么commit呀,它只能在这,因为这是个方法呀,那我问你,你这么写对吗?你这开一下,你这提交一下银行转账是不是两条update语句。
04:02
银行转账是两条update语句联合起来才能完成,对吧,但是你刚刚做完一个你就提交。嗯。这这要要你要说的话,那就前面都白学了啊。你得好好考虑呀,是吧,你不要说老师这这里面有连接对象啊,有连接对象就能控制事物啊,对你说的很正确,有连接对象确实能控制事物,但是这控制早了。你在这个方法里边控制的范围是不是有点小。你一个update语句可能是完成不了一个完整的事物的,所以我们说过了啊,一个事物完成之后才能提交,你不能贸然提交,你说你你一个账户里边减了1万块钱,另外一个账户还没有加那1万块钱呢,你跟他提交了。是不是肯定不能在这儿控制啊?我说过没有,今天上午说了,道跟啥没关系,道跟业务无关道德业务无关事物和业务有关系吗?
05:12
事务和业务是不是绑定在一起的?那你这在道里边控制不太合适吧。到哪有业务啊。倒没有业务啊是吧,所以这边呢,我要先写一个结论啊,这个结论呢,希望大家能够记住,来我在这写上就是说。控制事物啊,不能在道中控制,不能在道层控制,因为什么呢?因为事物和业务紧密相关啊,紧密相关的在道中啊,没有什么业务逻辑。哎,通通通常什么通常是N条吧啊DML语句吧,共同什么联合起来吧,才能完成一个什么完整的事物吧,啊,完整的事物。
06:10
所以不能在这控制啊,你得搞清楚啊。它不能在这儿,你想想想想能想明白你你你现在你你打开啊,我说过了,一共三个类嘛,一个一个service一个道吗。是吧,那既然不能在道里边,咱咱捋捋吧,这个吧,Service。这个service,我问你这个方法是一个事儿吗。这个方法的执行完成是一件事完成了吗?是个转账吗?是一个update语句,再跟上一个update语句吧,这两个安一样的同时成功。要么同时失败吧,那我问你这两条语句应不应该放在同一个事物里边啊,应该吧,那显然是不是应该比较合适在service里边控制事物是吧?那么当然我问你啊,在在在里边能控制事物吗?
07:01
是不是肯定也行,因为它是比service还要更高一层,对吗?如果从这开启事务行吗?可以吧,到整个执行结束之后干什么提交什么事务行吗?这不是不是也可以呀,就就说吧,行不行吧,这肯定是也行,但是但是你这战线拉的是不是太长了。你这个事物的范围是不是扩的太大了,没必要扩这么大吧?你没必要扩这么大,你的事物没必要扩这么大,实际上你事物的最合适的控制位置在哪啊,在service的这个方法一般是一个方法,就是一个事物。因为你这一个方法是什么情是一个转正的方法,就是完成一个事儿的,所以你这个方法就对应了一个事物嘛,所以你肯定是在这控制,当然我说了啊,最不应该是在道里边控制啊,有同学就说老道啊,道控制不是。道里边控制不了啊,道里边是绝对控制不了事物的。
08:03
别看道里边有什么对象,狄仁杰他也没法控制事物。啊,所以能在service里边控制。也能在这个里边控制,但是这个select它控制范围有点大,没必要,因为这块你想想没有数据的操作,只有哪个有数据操作,只有这句话有数据操作。就这一句话是是这样的。所以呢,我们事物的放在这个位置上,放在我们这个service方法上。这一般情况下不是全部啊,一般情况下一个方法就是一个完整的事物了,所以这边呢,我们要说上去service层中的方法层,Service层和什么业务紧密相关,当我们一个业务啊完全完成之后啊,完成之后再提交数据吗?再提交数据,所以控制事物啊应该放在service层,一般一个方法对应一个完整的事物,方法开始执行开启之啊,方法开始执行开启事务,方法执行结束,结束事务啊结束事务就是这样。
09:24
比如说业务完成成功完,业务完全成功,完全成功则提交对吧,业务中间啊发生异常。择什么呢?回滚事物就行了,是吧,回滚事物就这样,一般都是这样的一个方法,就是一个也。就是一个就是一个事物,那这个serve light也能在这控制事物啊,也可以在这也可以在serve light中控制事物啊,因为service比谁呢?比service还要什么,还要高一层,还要高一层啊,但是这样的事物的范围啊,事物的范围就太大了。
10:08
太大了,没有这个必要啊,没有这个必要。所以最好的方法就是最好的控制事物放在什么呢?Service层中啊,所以我们这个结论呢,就是放到service里边去控制事物,行了,就是这样啊,这是这个版本,我还没有写东西啊。就现在从理论上给大家说一下啊,分析事物应该在哪个哪个类中控制呢?最好在service从中控制,不能在倒腾中制啊,也可以在。都,所以这几个词呢,你要注意一个是最好,一个是不能,还有是一也可以。
11:02
但是这种方式最推荐的行吧,推荐这种方式啊,推荐这种方式。这是第一个,好,继续分析啊,分析好了,第一个现在控制事物大家要注意了啊,以后呢,我们是在service这个类容控制事物,并且是在这个方法里边控制事物的,这两个必须联合起来,同时成功或者是同时失败,不能一半成功一半失败出问题啊,那么这边呢,大家想一想应该怎么做呢?要想控制事物是不是必须得拿连接对象。怎么拿链接对象没法拿呀。那链接怎么拿?你想你控制事物的话,你不是在这儿吗?在哪呢,在这个。你看到那这里边你肯定得有个什么什么BBU吧,那点什么begin,你begin方法DB要点begin一个方法是需要连接吗?嗯,需要连接,你没有连接对象,你没有办没有办法开启事物,所以大家得考虑了,我们这个service里边怎么去拿连接,我们试试啊,我们写一下行吗?
12:18
我们写一下吧,啊来。就对于当前这个项目来说,那我要在这控制事物的话,是不是就意味着在transfer这个方法里边必须在这干什么,拿什么对象,是不是连接对象,拿吧,拿上连接对象之后呢,我倒个包啊倒过来,然后呢,接下来connection等什么DB就点什么get connection什么,嗯,Get好,这边呢,我加一个什么呀。再看是吧,加个finally吧,好了,接下来呢,大家看一看啊,在这写什么D点什么begin吧,在这写什么D点什么吧,在这写什么点什么robot back吧,在这写D点。
13:05
写什么end吧,好,最后是did,点什么close吧,好了,我问大家,现在这个写成呢?这个写成呢?有一件事我需要说一下,这个连接对象还能不能在道里边关闭。就是这个连接对象开是吧,是不是只能等待这整个这个事物都结束之后,这个连接对象是不是才能释放掉,那么也就是说这个连接线的关闭不能再放到灶里边了是吧。所以你看啊,在道里边,你看你只要是拿到连接,最后是不是就把连接关了,嗯,都关了吧,所以就不能关这个连接了啊。这个连接不能关了再倒里边,因为这个连接对象是不是还在我们这儿用呢。行,我这个先不说了,先不提这个关闭的事儿啊,我就先这么写,那么begin和这个commit之间呢。
14:05
锂电和可密之间是不是这段代码?整个这个代码吧,我给它剪了啊放进去了啊,剪了放进去。那这样的话,咱们这个count呢,就可以定到什么了外边了吗。往上定义啊,定义成零,最后把这个count是不是返回啊,这个大家能看懂吗?就从这个位置开始begin,从这位置开始,是不是commit了,在这是不是回滚,这是不是结束回我写上吧,啊这边开启事物。这个叫提交事物吧,是吧,来,这个叫回滚事物吧,这个叫什么?结束物事物吧?好,这是我们改的程序啊,还有一个严重的问题啊。你开启事物的时候,调的方法是get connection,而这个get connection方法你只要调用一次,它就会连一次数据库吧?那么是不是就意味着我们这个DB要求get connection得出的这个连接connectionction对象,现在你DB要求点begin transaction,你开启事物开的是哪个连接定向事物啊?
15:17
开的是这个连接对象的事物,对吧,当你下边调用这个update的方法的时候呢,它底层这个update的方法在执行的时候,执行到这一行,是不是又调用了DB To Get connection方法又得到一个连接呀,那我问你这个连接对象。和这个连接对象。它是不是不是同一个连接对象,就是这个对象呢,和这个连接它肯定不是同一个连接。那你控制事物是不是根本就不管用?你说而我控制了呀,那不是控制人间了吗?你没控制住啊,为啥呀?你控制的是张三,结果你底层使用的是李四。明白吧,你在那你控制张三连接了,但是人家底层偷偷的创了,创了个什么连接啊,李四这样的连接。
16:08
那你肯定不管作用啊。你看你底层掉几次,Select一次吧,Select一次吧,还这个一次吧,还这一次吧,那问你掉底掉里边几次吗?掉到里边的四次,其实是两个方法,掉了四次吧。在外加这个方法,大家想一想,是不是底层执行这个程序一共创造五个连接立项。五个吧。哎,这样吧,试试啊。要不然大家呢,可能感觉不出来,我在这儿是不是都会掉这个方法,我能不能把这连接对象输出啊,行吧,我试试啊,看是不是创了五个连接这边呢,给它部署一下,然后我把服务器给它启动。好,启动啊。启动之后呢,我们一起来看一看咱们今天下午的内容呢,有可能有点难啊,但是呢,你得适应,必须得有事物,没有事物你的程序不安全,来我们看看这边了啊呃,我输进去一个B吧,啊这个,然后接下来呢,我在这啊看看啊嗯,数据库里边数据够不够啊,来我再重新给它恢复一下得了,那这边的话咱们打开它,打开它,然后这边我选上它直接执行好。
17:25
那数据恢复了吧,接下来我我我我点了啊看底层啊,看这看这边啊,我加个断点行吗。我加个断点,晚点加呢。我就我就我就往这加一个行吧,往这加一个啊来这边走了,他开始走这个service方法,那么接下来他会拿链接,拿连接呢,你进去吧,那这个时候就拿连接吧,往下走,往下走是不是输出一个连接。是吧,嗯,就是这个连接吗?那么接下来这个方法执行结束之后,大家想一想,是不是往下走就开启事务了,但是你这个开启事务是对谁起作用了,是不是对这个三什么EED51这个连接对象起的作用啊,接下来你是不是就掉了道里边方法呀,那到的话你就进去了,那你进去了,进里边之后,你往下走,你往下走,往下走,往下走,走到那一行你再进去,你看看再往下走,再往下走,你看那个连接对象是不是一个新的呀,什么1036B16了,那么你这成就结束了啊,我就简单的结束了,你看底层,你看一共几个连接对象,因为你一共连了五次数据库,底层连接对象是不是一共创了五个,可见这不行的,哪个有事物啊,这个有,剩下这四个是不是都没有,所以不行,你这种方式肯定是不行,你这个控制不了啊,不对,你这个。
18:42
好,所以大家现在开始想一个问题啊。什么问题啊?连接对象在整个程序中只呈现几次啊,一次是吧,嗯。哎,还有一个事儿我说了啊,这个连接对象好像在道里边不能关了吧。
19:00
所以这我就写成什么,那么来继续啊,这边也写成那吧,我先写成那啊然后呢,这边呢,这边我是不是写成什么,注意啊,必须在整个什么业务流程完成之后,事务提交之后啊,才能关闭什么连接对象嘛,嗯,关闭连接对象DB要求点close,这俩都写成什么,那是吧,啊就这样。开启事务啊,提交事务,回滚事务,结束事务,最后关闭链接,所以这边注意事项我写一写啊,所在每年中总,嗯,这个总结一下事务在哪个层控制啊,Service第二个知识点是什么,必须保证啊嗯,Service方法执行因为什么呢?因为在service层中控制什么事物啊,必须保证service层方法执行的连接对象和什么告中告。
20:12
方法中的连接对象是同一个。Service层中控制事物必须保证service方法执行的连接对象和到方法中的连接线是同一个啊,必须得保证。还有一个问题就是说必须在哪在service层。啊,或者service方法结束的时候,事物结束的时候。再将什么连接对象干什么关闭,不能在什么在倒方法中关闭什么连接对象吧,所以这边呢,我分析了这么几个东西,首先呢,再来说一下,第一个是我们的一个事物在哪个层控制,第二个是我们的控制事物呢,应该。
21:03
保证我们连接对象啊,只有几个呢,在只有一个,并且还得保证我们连接的关闭是在这关闭的。啊,是在这儿关闭的。不能在这个里边关闭。行,怎么办?这不这个道理的方法吗?啊。这不设的方法吗?怎么做呀?也简单吧。其实咱们班里边最起码应该有人想到了啊,就是方法传参这个连接项串出来之后,能不能调这个方法的时候,把这个连接项传进去可以吧,是不是就是难看点。
22:00
难看吧,这个把这个connection传进去行吗?下边材料方法再调的时候,把这个connection传进去可以吗?可以吧,好,再来再往下是不是掉了一次杠啊,再把连接上干什么?传进去吧,再传进去吧,好了,那这四个方法其实底层是几个方法两个啊,都报错了,再加加一个什么connection吧,好,那这样的话,这个地方是不是也加上connection啊,这样子好,那这样的话咱们宝包就行了,嗯,这就完成了,完成之后大家看一看,这边呢,我们就报错了,这边写什么。是不connection啊,来继续,这需要connection吗?也需要吧,还需要声明吗?不需要了吧,还需要获取吗?因为这个连接能不能直接拿来用啊,可以吧,那就这样不能关闭吧,好,再往下,这个是不是删掉也不用了,这个不用新建了吧,就直接拿就行了啊,这样就可以了。嗯,你看这个里边还有获取连接对象吗?没有了,全是在哪获取,就是在哪获取一次,然后开启方法,只要用到我就把参数干什么,传进去,传进去,传进去,传进去全部传进去。
23:11
那么这样的话是不是就是只有一个了啊,只有一个了。而且我们把事物也控制住了啊,这个连接上关闭,不能在那关了。在这关闭啊,所以有几个知识点呢,我刚才说了,来,我在这再总结一下,一。食物在车位的控制二。三位得到必须得连接电是同一个啊,目前版本目前项目中使用了什么方法,在调用的时候传参的方式吧,保证什么到保证service和道中的连接对象是什么,是同一个啊,最后关闭的时候要注意用这个吧,最后关闭的时候是要注意我们在service的关闭down啊还有一个重要的问题,你觉得这样就能解决一就就就能解决事物了吗?
24:11
这样就能解决了是吗?不行,这样有问题。表面看似好像啊,这开了吧,这是不是提交了,中间整个东西是不是看着也没问题吧?但是你想过没有,道里边的异常发生之后,你选择的是什么补货,而不是上方,你看你的道里边异常,你是不是只要发生异常你就抓住了,你是异常扔出去了吗?你异常没有扔出去,是不是就意味着我在service里面根本就抓不住?我抓不住异常,我去哪回滚去?我只有抓住异常是不是才能回滚啊,所以咱试试啊,这种方式还是不行,但是最起码我可以保证连接对象,连接对象是不是一个呀,来我可以把服务服务从这挤一下起了之后啊,要注意这边,咱们这边给他后退刷新,然后这边我点啊第一个走。
25:10
是不是只有一个呀,因为你这个方法只调了几次,你这个在这个地方是不是只调了一次get connection方法,剩下你的connection是不是都是传进去的,你的对象只有一个了,包括你调到道里边,灶里边用的connection是不是也是这个connection,因为是传过去的嘛,能理解吧。哎,等我再下次再点的话,大家看一看是不是另外一个连接对象啊,这是不是很合理啊,一个线程几个连接对象,一个线程一个。是不是一个线程一个接对象啊,一个线程一个连接对象。一个线程一个连接对象啊,保证一个线程一个连接对象,好,现在我把这个讲一讲,为什么必须保证一个线程一个连接对象。
26:00
如果两个线程共享同一个连接对象,会出什么问题?有没有可能人家刚刚开启事务。另外一个人事务结束了,提交了,有没有这种情况,你看啊,Connection这个对象能共享吗?不能,Connection应该是一个线程,一个他们的服务器支持不支持多线程。支持吧,就是你访问的时候,你从这能访问吗?就是我这个服务器一开,然后你访问你转账,然后你从这也转账,你们是两个线程吗?你们是两个线程,你们既然是两个线程。两个线程不能共享一个connection对象。因为你要控制事物的话。你肯定对你这个连接项设置开启事务和提交事务,当别人同时也用这个连接项开启事务和提交事务的时候,那是不是就乱了?比如说你刚刚把事物干成begin了,开始了,接下来让你同桌呢?事物想结束了,他一结束是不是commit提交了,所以你想一想,是不是张三有张三的连接,李四呢,应该有李四的连接对象,这个连接对象是不是不能共享。
27:06
所以我这有一句话呢,希望大家能够理解,叫保证一个线程一个连对象,记住切记啊,不能不能有这种效果啊,就是不能让多个线程共享什么同一个连接对象,这样啊事物就混乱了。不能让多本线共享成同一个连立项,所以大家想,我不知道刚才有没有同学想了一个办法啊,就是说把这个连接对象生成生命成单立的,那这样的话是不是也能保证,呃,这个这个service的方法在执行的时候跟道理的方法执行的时候是在同一个,这个是同一个连接对象,能不能保证?我就现在不传参了,我这个参数我不传进去,咱们班里边有没有同学想到一种办法,就是把它生明成单立的,生命成静态的,那这样的话,将来我只要用的话就取这个静态的变量,那你取的话,这个对象是不是也只有一个啊,但是你想过没有那种方式是不是?
28:02
多个线程就共用一个了。是吧?那你你得比如说你比你比如说啊,我这个不是有一个工具类叫DP吗?这个DP我就不在这new了是吧,怎么办,我可以在这加一个东西啊,有同学是这么想的啊上一个吧,有同学这么想的,所以我我这还是说一下啊SKY个connection吧,那connection connection吧,那这边怎么办呀,是不是判断一下啊,如果这个什么可奈要是要是干什么等于等于,那怎么办就就就怎么办,就就就拗一下吧,啊就拗一下,那么其他情况我问你是不是第只有第一次访问的时候是等于空的,是不是就附上去了,当第二次再调用这个方法的时候,是不是直接把这个C就返回了。是这意思吧,所以这样是不是也可以保证这个connection只有几个一个,但是这么做太危险,这么做就彻底只有几个了一个了,你这么只有一个会有什么问题啊?
29:02
所有线程只有一个呀,那你事物岂不是混乱了,一会儿一个开,一会儿一个提交了,你看等还没等我还没还没等我开启呢,你这提交了。是这意思吧,所以不行,所以这种方式呢,我们希望大家也能想到,但是这种方式不能用,不能用这种方式为什么不能用,你也得知道这个事儿,为什么它不能用啊,在我们程序执行过程中,连接对象它不能够共享。连接上不能共享,我们在同一个线程里边能共享,明白吧,叫一个线程一个什么连接,哎,我问你,我现在这个程序达到了没达到一个线程一个连接。我只要穿的边方向直行是第二该的跟什么,我只要另外一个人在执行,是不是就穿一个新的了?但是我可不可以保证在同一个线程里面只有一个呀?可以吧?你要我调这个方法,是不是把它传进去在同一线程中吗?我调这个方法把它传进就在同一线程中啊,所以我现在可以保证啊,一个线程一个连接。
30:04
所以说我这写上一个注意吧,啊,写上一个注意啊,不能将什么连接对象啊声明层。单立的对象。啊。呃,如果连接对象啊只有一个,导致所有线程共享同一个连接,共享同一个连接对象啊,事物混乱啊事物混乱,所以这个你得注意。注意吧,啊,这个东西这个。所以这个呢,虽然我没有写太多的代码,但是呢这个很重要,来我来再总结一下吧,第一个我刚刚讲过了,得在这控制思路啊,这是你第一个需要记住的。
31:05
第二个知识点呢,就是说你怎么保证现在的service方法在执行过程中,和你底层调到的时候,这个连接对象是什么同一个。而且是一个线程一个怎么保证?一种方式叫传参方法,在调用的时候将参数传进去,这个时候可以保证在同一个线程中,这个对象只有几个一个,当我们下一个线程再调这个方法的时候,自然会新建一个新的连接对象,所以是一个线程一个连接,然后必须得注意啊,不能让所有线程共享同一个连接对象。还有一个问题就是这个关于connection对象最后关闭在哪关,那很重要,记住了啊,一定是在事物结束之后,连接对象才能释放。就这么几个知识点啊呃,还有一个问题来哪个问题来着讲着讲讲到哪了,异常吗?异常啊,来道路的异常应该干什么?上抛啊,来这写上道中的异常,道中的异常需要上抛给service,因为在service中需要使用什么cash补货吧,需要使用cash补货啊。
32:19
笑声,开除。捕获异常之后才能什么回滚,明白吧,才能回滚,保证数据的安全啊,数据的安全。好。所以大家想一想,呃,我先测一下吧,这么写是不是有问题啊,是吧,我先测一下啊,要不然大家呢,可能也是不太不太不太明白啊呃,我这样,我把这个这个这个这个滴滴优秀里边的这个这个什么输出就删掉吧,啊跟这个没关系了,那么接下来呢,咱们来测一测这个安全还是不安全吧,行吧,咱们转账的时候应该在道里边啊,我加个东西,我现在是不是异常抓住了,我没抛吧,没抛啊,哎,我这异常是不是抓住了呀,我也没抛吧,我没抛啊,这都没有抛,没有抛就有问题了,比如说我在这准备个int类型I等于多少啊零,接下来呢,我只要执行这个update语句,只要执行一次,我让他挨干什么,加加。
33:19
行不行,然后接下来呢,我怎么办呀,判断一下,如果I呀,要是等于等于二的话,我就我就在这提点什么呢?Pass in ABC,大家想想这个是不是会会出异常,也就是说这个update句会执行几次,在转账中update语句需要方法执行两次,第一次执行的时候呢,这个条件不成立,所以没有抛出异常,就执行这个了,数据库就更新了,当我们第二次再调这个方法的时候,A加就变成二,条件成立,会抛出异常,这个就不再执行了,那么这个时候数据安全不安全,我们可以试一下了,嗯。因为你在这出现异常之后,你抛出了吗?你是不是补货了,补货之后你想一想这个信息没有抛出,你是不是在service里边根本就没有回滚试试吧,啊看是什么样的,接下来把它部署一下,然后把服务器起一下啊。
34:10
挤一下之后呢,对了,这个数据库的数据我得恢复一下先啊,来选中这个执行变成多少五万一万啊没有问题,来清空,接下来后退,然后我刷新,接下来我点转账。是不是肯定会出问题啊,肯定会出问题啊,这出现这个叫什么for,什么input string ABC,它数字格式化异常呗,啊接下来我们看这个数据啊,来查一下。啊,怎么回事啊,少了吧,少了1万块钱呢,那为什么会少了1万块钱啊?因为没有回滚,你在这个service方法里边为什么没有回滚呢?因为你没有抓住异常,为什么没有抓住异常呢?是因为上面出现异常没抛出去,你上面这个到出现异常,你根本就没有上抛,你选择的是补货,你只要补货住,它就不会往上抛。
35:11
不往上抛,那个影响回滚吧,所以这个时候你得注意啊,怎么做呀,抓住异常咱们就抛出去呗,你用一个什么from time except行不行啊,可以把这种方式,这种方式行不行可以啊,这叫什么错误啊,叫查询吧,查询账户异常吧,来把这个复制一下,咱们直接贴过来放到这,这个出现异常之后怎么办啊,咱是不是也是打印异常对战必须上报啊,上报什么,这叫什么更新吧,更新账户异常啊,那我得写上去,你想一想补过了,然后呢,你打印之后再往上抛。当然你也可以不补货,对不对,你也直接把这个是不是也可以写到这啊,可以写到这儿啊,但是这种方式我愿意补货啊,为什么补货中之后,将来程序出现异常之后,是不是可以把这个异常具体的信息打出来呀,这样的话,将来我是不是可以看那个信息来调错呀,也行,所以我抓住,抓住之后我为了。
36:08
那个能够往上抛,所以我自己手动抛行吗?抓住之后再手动抛行吗?可以啊,手动抛嘛,这叫手动抛出什么异常好,这个方式咱们尝试一下看行不行,这个异常是不是还是会报这个异常,那肯定还是会报这个异常啊,但是这次呢,这个数据应该是没有问题的,对吗?来,我把服务器启一下,这样啊,我把数据库再恢复一下行吗?来我再恢复一下,一个变成五万一个变成1万,行了,成功了,这个再清空,清空之后呢,这个后退,后退之后呢,我们刷新,刷新之后我们点转账,转账之后转账失败,这是不是还是出问题啊,出问题但是数据你看啊,来选中它去执行,嗯,没事。五万一万没事,为什么这回没事呢?因为你现在啊,在service里边,是不是你这个抓住了呀,抓住之后你就你你就在这儿那个什么回滚了吧,你一回滚它就正常了。
37:04
明白我的意思吧,所以这里面有很多细节需要你注意啊,这东西很有意思,这边的道路的异常需要上报给service。道中的异常需要上报给service啊,因为service中需要使用cash补货,补货异常之后才能回滚,保障数据的安全。啊,这样的话,这个版本我就过了,大家呢,回顾一下我这个版本动了哪些东西。就是你上午不是写到三版本吗?对吧,三版本写第四版本的话,动了哪些东西啊,捋捋我就不再打开了,大家说一下吧,第一个是动什么。连接对象的获取。在哪获取啊service,然后把那个连接对象传给到了啊,传给到啊方法传参第二个呢,动了哪啊。
38:01
连接对象的关闭在哪关闭啊,Service关闭在道里边不能关吗?还有一个什么,还有异常的问题吧,异常的问题啊,在道路异常得上抛啊抛给service service补货才能回滚吧,嗯,就改了这么几个啊。嗯,在这儿的这个。到那这个删了吧,对了,咱们还没测正常啊,那这如果要是不出异常的话,别到时候也转不了账,这这这不好啊。所以这个东西咱们不再试一下,如果不出现异常的话,能不能正常转账也得测一测啊,坏的测,好的也测,都得测啊,来把福气再起一下。嗯,这个咱们听一下,嗯,这个咱们后退啊,后退之后咱们刷新,刷新之后我们点转账。应该是问题不大啊,然后这边呢,我们再把这个数据呢,查一下这个啊来查一下好吧,是吧,没问题啊,这样的话,咱们这个例子就做完了。
39:06
也就是说第三个版本你就不用练了啊,你就练第四个吧。这个又改了又改了不一样了啊,在service里边这个地方有这个connection。提交。开启事务,回滚事务,结束事,关闭连接对象啊,关闭连接对象。这问题又来了吧,什么问题啊,在service里边,你看写这么多JDBC代码好像。是吧?好像有点违背那个什么了吧,嗯,你service service你是跟什么有关系啊,跟业务有关系是吧,你整半天在业务里面写这么多JDBC代码。
40:08
还有一个问题啊,这个参数是不是在这是个累赘啊,你看你这样是不是会导致我们这个这个里边有个connection,完了这有个connection吧,下边有个connection,那每个方法调的时候都得传connection,这挺烦的。能不能把参数给我隐藏起来,这也很重要啊,所以咱们就得再再讲个东西吧啊,才能解释这个问题。好,这个版本很重要啊,因为和事物有关系了,再强调一下啊,这个事物的和数据有关系,数据不安全,你项目写的再漂亮那也是白搭啊,所以这个事物你必须得控制住。控制住啊,怎么控制,在service里边控制连接对象怎么办?只有几个,一个线程,只有一个连接,怎么保证一个线程一个连接。啊,然后呢,这个到的这个这个关于连接对象的关闭啊,在在在哪在哪关啊,异常上抛还是看是这个都要考虑清楚啊,一系列问题考虑清楚之后,我们异常才能控制住啊,我们这个事物才能控制住啊好了,那这样的话,咱们这个就版本就过了,嗯,接下来呢。
41:16
咱们得搞一搞啊,把这个再改一下第五个版本。来这个删掉啊OK。这个关闭。第五个打开这个。这个停掉啊,这个咱们部署一下添加走走bank OK OK好了,打开数据恢复点中这个直接运行五万一万好,没问题啊,大家现在开始想一想,我们必须得解决一个问题,这个问题我们必须解决哪个问题,就是关于这个问题,船舱问题。
42:01
我们以后不要这样做了。你这样传真很很不好看。那个。为了什么呢?为了保证service方法中的连接对象和道中的连接对象是同一个啊,我们使用了方法的传参方式啊,方法传参的方式保证了啊,但是这种方式不好看啊,但是这种方式会导致在倒层中的每一个方法上都有一个什么参数,都有一个connection参数。啊,有点多余吧,啊有点多余啊,这个有点多余。或者是代码没有复用吧,代码没有复用啊,代码没有复用,你想一想,你每个里边都写呀。
43:02
想办法啊,达到注意想办法啊,呃,达到什么呢。隐藏参数啊,将最好啊。最好将倒层每一个方法上的什么connection参数干什么隐藏起来。如何隐藏?就是咱们奔着一个目标就行了,那个目标一个线程,几个连接,一个连接,这就是我们的开发原则吧,就是开发原则啊,我们只要达到这个原则就行了。一个线程,一个连接。怎么才能获得一个线程,一个连接?
44:04
啊。好好想想这个了。你这这这这这创这有连接了,你就传呀,你就传呀,你传了几次啊四次你这你这会导致你看这方法多难看呀,这里面要有一要有100个这样的方法,那这个方法上面都有这么一个参数啊,都有这么一个参数啊,你好好考虑一下,这个参数是不是可以不写,如果不写的话,你如果还能保证一个线程一个连接对象的话,那多好啊。是吧,那所以这个东西你得好好考虑一下啊啊。但是你不能这么想,你不能这样想,你说你在这儿把它生命成静态的,生明成一个。你想要是把它生成成一个,是不是多线程共享一个了。不能多线程共享一个啊,我再强调一下,必须还得保证一个线程一个,你怎么能保证这个连接对象是一个线程一个呢?
45:05
那不行,那不行,你这不开玩笑吗?是吧,你说加上锁之后,你锁上了你能转账,别人转不了。都排队呗,都排练,这想法是不错的啊,那把这个肯耐森锁住了,你锁住那倒好了,锁住了你就排队了,排队你说我我我在这北京取个款,你一个在南京取款,等着吧,北京取款我才能取。肯定不能这样啊,你把联系对象锁,你这锁的范围,你胆有点太大了,这锁的锁的范围太大了啊,不能锁。不能锁,这是一个办法,它肯定是可以的,但是你锁住呢,有点。太过分了啊,思路。你锁住别人都用不了了,你说吧。
46:09
点击十。先别往连接池那想,咱们咱们现在这个还没搞明连接池,那想跟连接池没有关系。反正是肯定有办法,我提个醒啊,往线层那块想,往线层那块想,你就能解决这个问题了。就是你们以前学过的线程啊,只要往线程那边想,你就能保证一个线程绑定上一个连接对象了。这个得得给大家时间想,好好想一下,这个很重要,你要能想出来这个东西,我基本上也不用什么讲了啊,我一说你就明白了,要不然一会我写出来,你根本不知道我在写什么。这个代码其实很有意思。
47:07
这样吧,大家先休息一会儿想吧啊,课间想一想,然后下节课我找同学说一下啊,看看能不能说上来啊。这问题是什么呀?一个线程。一个连接,还还还还还不用什么,还不用传参方式。怎么能保证啊,我就是想把这个参数去了。搜一下了啊。
我来说两句