使用redis分布式锁 更改数据库 和更新redis缓存 + 锁续命 demo

网友投稿 636 2023-04-06

使用redis分布式锁 更改数据库 和更新redis缓存 + 锁续命 demo

使用redis分布式锁  更改数据库 和更新redis缓存  + 锁续命 demo

测试样例:

package com...redis.redisSuo.demo;import com...redis.RedisPoolUtils;import com...redis.redisSuo.JedisSuoUtils;import redis.clients.jedis.Jedis;import...RecordSet;import...SQL;import java.util.UUID;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;public class demo { private static RedisPoolUtils redisPoolUtils = new RedisPoolUtils(); private final static String key = "keys"; private static final int Thread_num = 20; private static final CyclicBarrier cb = new CyclicBarrier(Thread_num); public static void sendThreads() throws InterruptedException { Thread [] threads = new Thread[Thread_num]; for(int i=0;i"+lockRequestId); Jedis jedis = redisPoolUtils.getResource(); try { while (true) { //获取分布式锁,时间设为3秒 boolean getLock = JedisSuoUtils.tryGetDistributedLock(jedis, lockKey, lockRequestId, 3000); System.out.println(Thread.currentThread().getName() + "获取锁的结果:--->" + getLock); if (getLock) { int count = 1; String st_fj_id = key; String updateSql = "update dang_fj set count = count-? where st_fj_id = ? and count>=1"; Object[] updateObject = new Object[] {count,st_fj_id}; RecordSet updateRs = SQL.execute(updateSql,updateObject); int number = updateRs.TOTAL_RECORD_COUNT; //影响行数 System.out.println("数据库影响行数:"+number); if(number==1){ String counts = ""; String selectSql = "select * from dang_fj where st_fj_id = ?"; Object[] selectObject = new Object[]{key}; RecordSet selectRs = SQL.execute(selectSql, selectObject); while (selectRs.next()) { counts = selectRs.getString("COUNT"); } System.out.println("数据库剩余---->"+counts); String redisRs = jedis.setex(redisKey,60*60,counts); System.out.println("更改redis结果--->:"+redisRs); return Thread.currentThread().getName() + "去数据库拿结果~~~~:" + counts; }else { return Thread.currentThread().getName() + "更改数据库失败~~~~"; } } try { Thread.sleep(1000); } catch (InterruptedException ignored) { } } } catch (Exception e) { e.printStackTrace(); }finally { //不论结果如何,一定要释放锁 boolean releaseLock = JedisSuoUtils.releaseDistributedLock(jedis, lockKey, lockRequestId); jedis.close(); System.out.println(Thread.currentThread().getName()+"释放锁的结果:--->"+releaseLock); } return Thread.currentThread().getName()+"最后结果lockRequestId--->"+lockRequestId; }}

加锁解锁 工具类:

package com...redis.redisSuo;import redis.clients.jedis.Jedis;import java.util.Collections;/** * @author * @date 2019/8/10 */public class JedisSuoUtils { private static final String LOCK_SUCCESS = "OK"; private static final String SET_IF_NOT_EXIST = "NX"; private static final String SET_WITH_EXPIRE_TIME = "PX"; private static final Long RELEASE_SUCCESS = 1L; /** * 尝试获取分布式锁 * * @param jedis Redis客户端 * @param lockKey 锁 * @param requestId 请求标识 * @param expireTime 超期时间, 单位毫秒 * @return 是否获取成功 */ public static boolean tryGetDistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime) { String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime); return LOCK_SUCCESS.equals(result); } /** * 释放分布式锁 * * @param jedis Redis客户端 * @param lockKey 锁 * @param requestId 请求标识 * @return 是否释放成功 */ public static boolean releaseDistributedLock(Jedis jedis, String lockKey, String requestId) { String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId)); return result.equals(RELEASE_SUCCESS); }}

锁续命小demo:

// 加锁后开始调用方法 :开个子线程,原来时间30,每隔30/3,重置为30 LockService.renewLock(lock.intern(),driverId,30);接口:package com....service;public interface LockService { /** * 续约 * @param key * @param value * @param time */ public void Lock(String key , String value , int time);实现:package com.....impl;import com.....LockService;import org.apache.commons.lang.StringUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Service;import java.util.concurrent.TimeUnit;@Servicepublic class LockServiceImpl implements LockService { @Autowired private RedisTemplate redisTemplate; @Override @Async public void Lock(String key, String value, int time) { String v = redisTemplate.opsForValue().get(key); if (StringUtils.isNotBlank(v) && v.equals(value)){ System.out.println("进入续命操作... "+key+" "+value); int sleepTime = time / 3; try { Thread.sleep(sleepTime * 1000); } catch (InterruptedException e) { e.printStackTrace(); } redisTemplate.expire(key,time,TimeUnit.SECONDS); Lock(key,value,time); } }}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:分布式数据库数据一致性的原理、与技术实现方案
下一篇:列式分布式数据库ClickHouse部署
相关文章