Mysql分布式锁(三)悲观锁实现并发 落日映苍穹つ 2024-03-30 10:16 17阅读 0赞 在前面的方法中,一条sql语句中仍然存在着很多问题,于是我们可以用悲观锁来代替解决。 假设我们不用一条sql,仍然用先查询,判断,最后更新来实现业务。 #### 文章目录 #### * * 悲观锁 select...for update * * 1. 不加悲观锁 * * 1) 两个机器连接mysql * 2)机器1查询1001 * 3)机器2更新1001 * 2. 加悲观锁 * * 1) 机器1查询1001 select ...for update * * 2) 机器2尝试更新1001 * 3) 机器1commit,机器2更新操作才完成 * 悲观锁运用到项目中 * * 1. 修改业务代码 * 2.Jmeter 测试 * 3. 问题 * * 1) 性能问题 * 2)死锁问题 * 3)库存操作要统一 ### 悲观锁 select…for update ### #### 1. 不加悲观锁 #### ##### 1) 两个机器连接mysql ##### 目前数据库数据如下 ![在这里插入图片描述][a159a6e6b8c54e81a41cdc7c7874984d.png] ##### 2)机器1查询1001 ##### ![在这里插入图片描述][d7d6e3bbe59644bab2664c372fd864ff.png] ##### 3)机器2更新1001 ##### ![在这里插入图片描述][2b37e6775f554a72a6ed55c8d31efea7.png] 更新成功,此时机器1中查询到的数据,明显就是不对的。 如何解决呢? #### 2. 加悲观锁 #### ##### 1) 机器1查询1001 select …for update ##### **一定要先开启事务** > begin; > select count from db\_stock where product\_code = ‘1001’ for update; ![在这里插入图片描述][0390d411c0cf4e749bbc2fb470bda9fb.png] ###### 2) 机器2尝试更新1001 ###### ![在这里插入图片描述][cbc8ccce8c65405192520b170869d97c.png] 阻塞住了 ##### 3) 机器1commit,机器2更新操作才完成 ##### ![在这里插入图片描述][faef9f9b791c4df2aa5691507c18c8dd.png] 很显然,阻塞了20秒。 ### 悲观锁运用到项目中 ### #### 1. 修改业务代码 #### StockMapper @Mapper public interface StockMapper extends BaseMapper<Stock> { @Select("select * from db_stock where product_code = #{productCode} for update ") List<Stock> selectCount(String productCode); } StockService @Service public class StockService { @Autowired private StockMapper stockMapper; @Transactional public void deduct() { // 1。 查询库存 List<Stock> list = stockMapper.selectCount("1001"); // 2。 判断条件是否满足 if (!CollectionUtils.isEmpty(list)) { // 假设就拿第一个北京仓的 Stock stock = list.get(0); if (stock != null && stock.getCount() > 0) { // 3。 更新库存 stock.setCount(stock.getCount() - 1); stockMapper.updateById(stock); System.out.println("当前库存" + stock.getCount()); } } } } 之前这样的业务逻辑,并发测试是有问题的,现在替换成了悲观锁,并发测试下。 #### 2.Jmeter 测试 #### ![在这里插入图片描述][afb714b8b6c044249caac10550125bc7.png] 无报错,吞吐量才20,太低了 ![在这里插入图片描述][0a47e36be962450e9097bf9a2fe064f2.png] 数据库数据成功清0,问题解决。但是比一条sql的吞吐量明显降低。 #### 3. 问题 #### ##### 1) 性能问题 ##### 吞吐量明显降低 ##### 2)死锁问题 ##### 示例: 机器1悲观锁查询id=1 ![在这里插入图片描述][0ef076989e88443e89b34eaada8edb91.png] 机器2悲观锁查询id=2 ![在这里插入图片描述][8026ab1706174c10a1d073e712cc6f0b.png] 机器1悲观锁查询id=2,阻塞住了 ![在这里插入图片描述][7447f1ce4db54ff597aeef7c535bb122.png] 机器2悲观锁查询id=1,发生死锁 ![在这里插入图片描述][2afceb7346f74b2aa7177cdafa17b030.png] ##### 3)库存操作要统一 ##### 如果用select…for update, 那业务中其他查询也要用悲观锁,而不能只用select 因为如果其他查询用的select,那查询的数据还是有可能被其他线程修改,导致并发数据问题。 [a159a6e6b8c54e81a41cdc7c7874984d.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/edbd05a1071b4751a2a375dc8cd944f0.png [d7d6e3bbe59644bab2664c372fd864ff.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/6fe3d6fb99134ea9a8f454f923bc3d70.png [2b37e6775f554a72a6ed55c8d31efea7.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/3a962e3bf6b44114b9653cbf0e61dce9.png [0390d411c0cf4e749bbc2fb470bda9fb.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/513facd2e82244728a945d3528850812.png [cbc8ccce8c65405192520b170869d97c.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/540733e39c5a4fdf88344a2497b95dc7.png [faef9f9b791c4df2aa5691507c18c8dd.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/fa0252fbafea465b933c1af1f914597b.png [afb714b8b6c044249caac10550125bc7.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/db4fcf8aca724231bebe998732ea628f.png [0a47e36be962450e9097bf9a2fe064f2.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/a2011cb7fb634690adb4331653658cc7.png [0ef076989e88443e89b34eaada8edb91.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/3752881540bf48acb76526340edb9fcb.png [8026ab1706174c10a1d073e712cc6f0b.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/1360d4f00b734bc0a0f563956d2392f9.png [7447f1ce4db54ff597aeef7c535bb122.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/1190b31e3bf148f0b04854d849beb8c0.png [2afceb7346f74b2aa7177cdafa17b030.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/98e7a12b722c42a0ab6473cd8f50e79f.png
还没有评论,来说两句吧...