00:00
好,打开我们的ID啊编辑器,那么首先呢,我们需要给咱对应的那张表啊,来创建一个破角对象。那么这个配对象呢,我们可以给它创建出来,然后就命名为啊lock啊这样一个对象,那么然后这个lock对象呢,我们要加上这个data注解,那它有get set方法,那么样对应的表,我们可以来一个table name来指定一下对应的是TB lock这张表。那么然后里面的字段啊,咱无非就两个字段,那么一个private long IV这样一个字段,那么再来一个private,那是string啊,Lock name这个字段,那我们我们这个的话呢,使用的是驼峰。好,那么写好之后呀,我们还需要去创建对应的map接口。那么咱加锁和解锁呀,本质呢,就是对表来进行操作,那所以呢,咱就需要对应的实体类和map接口。
01:00
啊,那我们这道呢,实体类啊,已经有了这个map接口啊,我们给它创建出来。那咱就命名为,然后是lock,呃,Lock,然后是map,那么这应该是一个接口,把它改成in the face。让A继承我们这个base map,那么这样的话呢,咱单表操作呀,就不需要去写映射文件了。那么这个泛型啊,还是这个那个泛型,用这个lock的话呢,一定必须得是我们自己定义的这里个lock实体类啊,啊,千万不要引入错了,我们要引入这个。那么研究好之后啊,那我们再回到啊,咱们这个service里面去,我们来去改造一下那个减库存的这个代码啊。那咱可以呢,把这个减库存方法呀,再重新拷一点出来啊,给它放到咱们这个下面去,那放下去之后呢,我们再把这个地方呢,改成。那十对吧,改成十应该到十这个位置了啊,之前到九这个位置,它改成十。
02:04
改原式之后呢,咱再把这个抵押的方法呀,还原回去,那么最初的那个样子呢,是没有这个东西的啊,也没有这些东西,那么这是最初的那个样子啊。那我们在这个基础上,我们来去改造一下咱们这个程序,那么首先呢,我们为了保证原子性,咱们在操作之前,我们需要以加锁。那么然后呢,加锁呃,成功之后呀,我们开始执行这个业务操作,那么执行完了之后呢,我们要进行解锁的操作啊,最后呢,要进行解锁。那么然后呢,如果我加锁失败了,我可能还要进行重试。那我们这里的话呢,加锁和解锁呀,咱就不再去封装成一个工具类了啊,咱就直接呢在这里去玩一下,因为my circle的这个分布式所呢,说实话在企业开发里面呢,使用的不是很多。那为什么使用的不是很多呢?啊,等咱写完之后,压完之后呀,你就知道啊,为什么用的不是很多了,因为它有严重的性能问题。
03:08
好,那我们这的话呢,咱就通过这个拉迈接口那么来加锁,那所有的加速呀,其实就是新增一条记录嘛。OK,那我们呢,先把这个lock map接口啊注入进来,来一个啊lock啊lock map啊lock map,那么然后呢,来一个的好中进来之后呀,我们加锁呢,就是新增一条记录,大家又通过为点lock map点一下insert。好,那我们这里面啊,就需要一个lock对象,这个lock对象啊,咱们可以通过没一个lock。啊,这样的一个对象,那最终返回的呀,是一个lock,那咱给这个lock来设置一下锁的名称就可以了,那只要不重复就行,咱们可以来一个啊log就叫这个名字。那么然后呢,再把这个lock对象啊,给它放在我们这个insert里面去,好,那么这样呢,就在加锁了啊。
04:05
那么一旦出现异常代表呢?是呃,加锁失败,我们可以进行重试。OK,那么咱们可以来一个check,那么此时呢,代表加锁失败,我们可以进行重试啊,那么这个异常啊,我们给它捕获那个最大的那个异常啊。啊,然后在这个里面呢,我们可以进行呃重试了啊,但我这个异常捕获的不够精确啊,咱应该是捕获的那个CQ那个异常。好,那咱这边呢,其实也没有其他地方可能会有异常啊,也就这个地方可能会出现异常啊。好,现在我这里呢,就随便搞一搞啊,啊,最终能测出啊,那个效果就可以了。好,这个的话呢,我们嗯来进行重试,所以的重试呀,它就可以地位调用嘛,啊the.dedu这样的一个方法。那么在递归调用的时候呢,我们最好能睡一会儿啊,再进行重试啊,来一个瑞点下sleep,比如就睡一个50毫秒啊,应该足够了啊。
05:04
好,我们再来一个啊try catch方法,把这个异常呢给它捕获一下。啊,然后呢,一旦获取锁成功,我们开始执行业务操作,那么执行完了,我们来进行解锁呀。好,那这个解锁的话呢,本质就是一个删除啊,删除对应的记录。啊,this.lock map点上啊是delete by ID,我们一定要使用delete by ID。啊,为什么要使用它呢?啊,因为它可以防止误删。那你新增的时候,你加属的时候,你新增一条记录,那新增这条记录的时候呀,默认情况下,MY会通过组件回血啊,给我们这个对象啊,设置一个ID上去。那我们在这个地方呢,就删除对应这个ID对应的锁就可以了啊,那以防止呢误删。那我们知道咱们这个ID啊,是数据库自增的啊,我每次新增记录的时候,这个ID都不一样,那不同线程获取锁的时候,本质新增记录呀。
06:02
那你新增记录的话呢,这个ID呢,是不重复的啊,那我们呢,可以直接把lock对象里面这个ID给它放进去就行了。好,那么这是咱们这个加锁解锁以及重式我们就已经完成了。啊,咱这简陋的完成了啊啊其实呢,有很多可以优化的点。那我们呢,就不再去搞它了啊,咱就简单的去实现一下,看看能不能做到我们想要的那个效果。好,我们就需要去重启咱们这两个服务。啊,让它重启的,首先的话呢,我们需要把咱这个库存数量重新改成5000件库存啊。那么改好之后呢,我们再来去,呃,到浏览器中去访问一下看看啊,应该都已经启动好了,我们可以访一下看看,我们来去刷新。啊,刷新刷新啊,应该都预热好了哈。那么预热好的情况下,再回到red里面去,那这个库存数量我刷了三次,呃,减了三件库存,我再改回这个5000啊,那么在浏览器中来访问呢,都是没有问题的。
07:09
但是呢,我们通过压力测试会不会有问题呢?我们可以压一下试试啊,那么这个地方呢,我们呃可以去,呃,这个5000啊已经开好了,对吧,改好了哈,改好了,那我们来去压力测试一下啊,我们来去执行压力测试。那么此时我们可以看到你这个性能呢,啊,非常的感人啊,就100多的这个吞吐量啊。啊,不会超过200的,以我的电脑来说啊,不会超过200。啊,那么然后呢,咱们这个,嗯,这个还差啊,还差很多啊来看啊,有没有错误的呢,没有出错的啊。好,最终我们的5000个请求呢?就已经执行成功了啊,执行完了错误率呢0%。那么然后呢,我们最终库存数量有没有减成零呢?啊,已经减成零了。那是么呢,说明咱们这个ma的分布式所啊,也可以保证我们碱库存的一个原子性。
我来说两句