tk网站的dns修改,站群 wordpress,建立旅游公司网站多钱,怎么把自己做的网站放到百度上一、前言
前一篇 Redis应用之二分布式锁 我们介绍了使用SETNX来实现分布式锁#xff0c;并且还遗留了一个Bug#xff0c;今天我们对代码进行优化#xff0c;然后介绍一下Redisson以及数据库的乐观锁悲观锁怎么用。
二、SetNX分布式锁优化后代码
RedisService.java Inven…一、前言
前一篇 Redis应用之二分布式锁 我们介绍了使用SETNX来实现分布式锁并且还遗留了一个Bug今天我们对代码进行优化然后介绍一下Redisson以及数据库的乐观锁悲观锁怎么用。
二、SetNX分布式锁优化后代码
RedisService.java InventoryMgrImpl.java 将代码部署在两台机器库存设置为10000 set inventory:9321785256118 10000然后Jemter创建两个线程组每个线程组起500个线程循环执行10次结果库存值为0没有产生并发问题。注这里每一次调用扣减一个库存。
注意点
1、设置锁的超时时间超时时间不能设置太短一定要比业务代码执行耗时最长的时间再大一些一般设置为3秒差不多上一篇文章用了Redis分布式锁还产生问题的原因就是因为超时时间设置太短造成的业务代码还未执行完锁就失效被另外一个线程持有然后在并发量大的情况就产生问题了。另外老版本Redis的SetNX好像是不能设置超时时间这个就必须自己去控制超时以避免死锁。
2、代码中当获取锁失败立即重新去获取这个会对redis造成冲击可以加入适当的休眠时间。 三、使用Redisson实现Redis分布式锁
Redisson是一个基于Redis扩展库提供了很多具有分布式环境特性的常用工具类我们这里用来使用它分布式锁机制。
1、加入依赖包 2、配置类 3、代码中获取锁 用100个线程两台机器压测未产生并发问题。
注高版本JDK比如JDK17Redisson运行时报错原因未确认。
以上不管是自己直接调用SetNX还是用Redisson做分布式锁都是基于单台Redis的如果是集群Redis会更复杂一些。
四、数据库锁
数据库锁也分为乐观锁和悲观锁这种方案在传统软件公司会采用比较多一些互联网公司一般不太采用数据库的特性去做事情主要是数据库负载相对来讲比较大会尽量避免。
1、乐观锁
认为数据一般不会发生冲突在数据提交更新时才会去检查数据是否冲突如果冲突不执行返回错误。
具体实现通过给表加一个version字段来实现当读取数据时将version字段的值一起读出数据每更新一次对此version值加一。当我们提交更新的时候判断当前version与开始取出来的版本值大小是否相等如果相等则予以更新否则认为出现并发问题不更新数据让用户重新操作。
创建库存表 SpringBoot整合JDBC InventoryManagerDB.java 不用数据库锁Jmeter开启两组线程每组1个线程循环500次最终库存数据是208肯定会产生并发问题。
代码中加上乐观锁
1、数据库增加version字段 2、InventoryManagerDB.java Jmeter开启两组线程每组1个线程循环500次最终库存数如下 这说明有307次变更库存是失败的693次变更成功但没有发生并发问题因为直接告诉用户失败了或者让用户采用重试机制。
2、悲观锁
对数据的冲突采取悲观的态度也就是假设数据肯定会冲突所以在数据开始读取的时候就把数据锁定住此时当其他事务如果要更新此条记录就会因为不能获得锁而阻塞。 注意这里查询的时候用主键然后加上for update锁定这条记录并且该方法要加上Transactional事务控制如果不是使用主键可能就把整张表锁住了。
Jmeter开启两组线程每组50个线程循环10次最终库存数据是0未产生并发问题。