00:00
基于以上三种原因,以后我们的共享资源如果是放在MYSQL这种关系型数据库的情况下,尽量避免呢,使用GM的利索。除非呢,你可以避免以下三种情况,一个多类模式,然后呢,与事物共存。以及呢,急性部署。那多类模式呢,很容易避免,因为它基本上呢,都是使用单例模式。但是呢,事物以及呢,即行部署是很难避免的。因为你的业务逻辑稍微复杂的情况下,我们就可能要保证使用事物来保证我们的原子性。使我们的操作要成功都成功,要失败都失败。那么集群部署呢,比如说我们的并发量比较高的情况下啊,逐渐增长的情况下,咱可能就要去集群部署。那么如果你的代码使用的是基本地锁,就有可能会出现并发性的问题。那怎么办呢?我们可还可以使合呢?使用my circle这种关系性数据库本身的一些锁机制来解决这样的一个问题。
01:01
但也有同学说,老师加什么锁呀,我一个SQ语句就搞定了,哎,锁都不允许加。好,我们来一起看一下啊,哎,他说的这种不加锁还是怎么回事呢。那我们来分析一下咱现有的代码啊。我们现有代码呢,是怎么玩的?咱们首先呢,会先去查询,第一步我们会查询库存,查询库存,那么第二步呢,我们会去判断库存是否充足,这是咱第二步。判断库存是否充足,那么第三步呢,我们才是去更新库存到数据库啊,更新。更新库存到数据到数据库,那么于是呢,就有同学说我完全可以一个思库语句搞定。那如果我一个SQ语句搞定了,哎,他就可以呢,解决这种并发性的问题啊,我们来看一下他说的一个SQL语句是怎么写的,首先更新呢,肯定是update。
02:07
更新我们的库存表,Talk这张表让他设置数量,肯定是在原先数量的基础上来去减一件库存。好,由于呢,我们这里每次请求是每一个商品,所以我们这减的数量呢,应该是减一。好,那么后续呢,咱应该是判断我减哪个商品的库存呢,那你肯定要去根据商品编号来进行查询。那我们这个列名呢,应该是product code等于1001,这个编号大家拷贝过来。放在这个中间。然后呢,我们还应该去判断库存数量。是否充足?那么之前呢,我们是判断库存数量大于零就可以了。为什么是大于零呢?因为啊,我们只买一件库存哈,每个请求只买一件。
03:03
那买一件只要大于零。那不就至少是一件了吗?好,那我们假如说我买的不是一件呢,一个请求,他比如过来了买了五件商品。那我减五件库存呢?这定要减五,那对应的这个判断还能判大于等于大于零嘛,肯定不能了,但现在就判断大于等于五件库存。所以呢,我们的思后语句后面这个位置。要判断的是大于等于,我们要减到库存数量。我们减几呢?减一,所以这个位置判断的时候呀,咱应该判断的是count大于等于一减库存。好,那我们这个更新的思语句呢,就已经写好了。那么这个C语句啊,它是它可以完整的表述出三个过程,那么然后呢,它具不具备原子性能,它当然也具备原子性。
04:00
因为呢,在my circle里面,我们的更新啊,包括新增以及delete啊删除这三个操作,这些写操作啊去操作,那本身就会加锁。加悲观锁。那么既然加锁了,那当然可以保证我们的原子性了,这就可以解决并发性的问题。好,那么咱建议呢,我们SQL语句写好之后呀,我们想在代码里面的演示,我不想去通过这三个步骤来完成了。我想通过这个SQL语句来看看好不好用。那么首先呢,咱需要在map里面得定义我们的方法了。好,来一个啊,返回值呢,是因此类型的,这是我们的影响条数。And update。Talk这个方法,那么这个方法呢,我们得要去写词后语句,我们可以通过注解的形式来以证明S语句。
05:06
好,那么这块语句呢,拷贝过来,让它放在咱们的这个里面去。那为了更加通用啊,那我们这个地方的这些参数,咱可以不用去写四。我们可以呢,用一些占用参数来表示。咱可以来一个井号,划括号,然后是count。那么这个位置呢,咱也可以呢。动态的弹力进来,我们可以通过一个单音符井号发括号,然后pro doctor code来去表示。那么后面这个位置呢,也有一个一,我们也可以使用井号画括号单一符,那就表示。要替换掉。那么我们的方法呢,就需要传这两个参数,那么你要更新哪个商品的库存。咱们得要来一个string或者dark cold。
06:01
以及呢,我们还需要更新的数量啊,这个抗的数量。那么由于呢,我们有多个参数,我们就需要去加派照母注解来指定参数名称。那我这两个参数,参数名称呢,分别是product code。那么还有呢,咱还一个count。这样的一个参数,咱们也可以去指定一下,把count也给它放入进来。好,那我们这样的,咱就把这个方法呀,给封装好了。封装好之后呢,我们在service里面再去试一试。那我之前呢,是这么去玩了,那我现在呢,不想这么去玩了,咱可以呢,把这一块呢。全部给它注释掉啊。就是表感性的,我们就直接。来一个注释。那么我们把它换成什么样子呢?咱可以给它换成这个样子啊,掉那个map里面的。那个更新库存的一个方法,来一个Z4.map点上。
07:02
然后呢,Update stock,刚才我们封装了一个方法。那我们要去给1001这个商品来减库存,咱们应该是双引号1001,那每个请求我就减一件库存。好,那我就这样调一下就行了呀。那调好之后呀,那我们这个锁还要不要了呢?那肯定不要了,那么这些呢,给它注释掉。啊,也没有加速,你可以认为我这个方法就这一行代码,就是更新库存这个方法,一个SQL语句搞定的。好,那么这些呢,都搞定之后呀,我们来去重新启动一下试试啊。那我这里呢,假如说我依然是集群部署的。一个呢是服务一,我们需要重新启动。那么然后服务二我们也要重新启动。重新启动。好,那么两台服务呢,启动应该没啥问题哈,都已经启动成功了,启动成功之后呢,我们在浏览器中来去访问一下,我们来去走好已经访问成功,那么此时我们的库存,那我们来去刷新一下,减为19了。
08:15
建了一点库存。那我们呢,再来去多刷几下来刷刷刷来看我们的库存数量,来刷一下来16。好,那我们给它改回5000件啊,然后使用压力测试工具,我们来压一下试试。保存好刷还是五天。打开压力测试工具,我们来去运行压力测试,那么你看我们的吞吐量。达到2000多啊,2000的吞吐量。迅速就完成了。那么有没有防止超卖呢?我们去刷新数据库来看剩零件库存,就完美解决了我们这样的一个问题。在集群情况下,它也可以解决我们的超卖现象啊,保证我们的现场安全。那虽然这种解决方案呢,诶看起来呢,还是非常不错的,兼顾线程安全及性能啊。
我来说两句