成都医院网站建设,制作个人网页的过程,建筑公司的名字怎么取才好,免费看行情的软件大全免费目录一#xff0c;场景说明二#xff0c;Redisson分布式锁1#xff0c;引入依赖2#xff0c;生成RedissonClient对象3#xff0c;测试三#xff0c;说明一#xff0c;场景说明
为什么需要分布式锁呢#xff1f;
如果是单机服务#xff0c;即只有一台服务器#xff…
目录一场景说明二Redisson分布式锁1引入依赖2生成RedissonClient对象3测试三说明一场景说明
为什么需要分布式锁呢
如果是单机服务即只有一台服务器那就不需要分布式锁在代码中加锁就可以满足需求了。在分布式环境下服务都是部署在多台机器普通锁已经无法满足需求了。以下面这个场景为例 有一个创建人员信息的模块前端页面中输入人员相关信息点击“保存”按钮发送请求后端收到请求后开始处理生成主键ID及其它信息安全起见可以在保存人员信息方法上加一个synchronized锁或者是ReentrantLock锁最后将人员信息保存到数据库中。假如前端没有控制好第一次点击“保存”按钮后并没有将按钮置为无效客户点了两次“保存”按钮发送了两次请求这样会怎么样 上述场景如果是在单机环境下是没有问题的因为加了锁即使发送两次请求第二次请求也会被阻塞等第一次请求执行完后才会执行代码中再加入一些判断判断数据库中是否已存在该人员信息如果存在不执行insert返回人员信息即可。如果是在分布式环境下服务部署一般都会采用Nginx来转发前端请求如果Nginx采用轮询方式第一次请求发送到A服务器第二次服务发送到B服务器两台服务器中获取synchronized锁都获取成功在数据库中查询发现不存在人员信息两台服务器都执行insert操作最后数据库中一个人员信息生成了两台数据出现问题。 出现上述情况就可以用Redisson的分布式锁来解决。通过Redisson的单线程特性在保存人员信息前先获取锁获取成功后才执行。 二Redisson分布式锁
1引入依赖
dependencygroupIdorg.redisson/groupIdartifactIdredisson/artifactIdversion3.11.2/version
/dependency2生成RedissonClient对象
Configuration
public class RedissonConfig {Beanpublic RedissonClient redissonClient(){Config config new Config();// 连接Redis如果Redis设置了密码可以通过setPassword()指定密码config.useSingleServer().setAddress(redis://192.168.1.5:6379);return Redisson.create(config);}
}3测试
GetMapping(/user)
public class UserController{Autowiredprivate UserService userService;Autowiredprivate RedissonClient redissonClient;PostMappingpublic User save(User user){userService.save(user);}
}public class UserServiceImpl implements UserService {Autowiredprivate UserDao userDao;Autowiredprivate RedissonClient redissonClient;Autowiredprivate StringRedisTemplate stringRedisTemplate;public User save(User user) {String key add_user_lock;RLock lock null;try {lock redissonClient.getLock(keyuser.getPsnNo());while (true) {if (lock.tryLock()) {break;}Thread.sleep(1000);}//业务代码String userstringRedisTemplate.opsForValue().get(user.getPsnNo());if(user){return (User)user;}else{User user userDao.save(user);//保存人员信息stringRedisTemplate.opsForValue().set(user.getPsnNo(),user.toString());return user;}} catch (Exception e) {e.printStackTrace();} finally {if (null ! lock lock.isHeldByCurrentThread()) {lock.unlock();}}}
}三说明
通过Redis的单线程可以实现分布式锁在第一次获得锁之后进行人员信息的保存并将人员信息以人员编号比如人员身份证号为key存入到Redis中第二次获得锁的请求会先去Redis中查询是否存在人员信息因为第一次请求已经将数据放入redis第二次请求发现Redis中有数据直接返回防止插入多条数据。Redisson除了上面的可重入锁外还有其它的锁可以根据实际情况进行选择。
//可重入锁
RLock lock redissonClient.getLock(lock);
//公平锁
RLock lock redissonClient.getFairLock(lock);
//信号量
RSemaphore semaphore redissonClient.getSemaphore(semaphore);
semaphore.trySetPermits(3);