这段时间有一个需要是要“开宝箱”,涉及到一个事务中有多个数据库表要同步更新,初始阶段没有加锁导致一系列并发问题(当大脑沉浸在业务逻辑上的思考时候很容易忽略,原谅我的狡辩),期间遇到一些“灵异现象”,但最后在高手的指点下渐渐明白了一些以前留在大脑却没有理解深刻的概念,比如分布式锁、悲观锁、乐观锁等。下面按照我解决问题的先后顺序和问题发酵的流程,一些罗列遇到的各种坑。
ReentranLock
第一步就是想在代码中加入同步锁,结构先是如下:
在整个黑色框代表的事务(逻辑包括从数据库中获取宝箱中的物品,按照权重随机函数选择其中一个物品,然后更新该物品为已使用)中,一开始把同步锁加在1,即锁住整个事务,进行junit测试并发,并发问题马上解决。初始成功后,为了优化下性能,我把同步锁换成在2的位置,此时并发问题再次到来——并发10个线程开启宝箱,可是最后数据库里消耗的物品记录并不是10个,而是3-4个,查看日志有好几条物品记录被重复消费。此时我的思维凝固在1和2之间的区域的差集中努力寻找bug,可是这段代码除了查询还是查询,不可能会存在并发问题。经过一番思考后发现其实错误不在这里。2位置将并发的线程都挡在这里,只有一条线程进入&#x