java redis分布式事务处理_记一个Redis分布式事务锁

packagecom.redis.mq.util;importredis.clients.jedis.Jedis;importjava.util.Collections;importjava.util.UUID;/***@authorxiaowu

* @date 2019-12-20

**/

public classRedisLock {/*** RedisLock的正确姿势

* 加锁:

* 通过setnx 向特定的key写入一个随机数,并设置失效时间,写入成功即加锁成功

* 注意点:

* 必须给锁设置一个失效时间 -----> 避免死锁

* 加锁时,每个节点产生一个随机字符串 -----> 避免锁误删

* 写入随机数与设置失效时间必须是同时 -----> 保证加锁的原子性

* 使用:

* SET key value NX PX 3000

*

* 解锁:

* 匹配随机数,删除redis上的特定的key数据,

* 要保证获取数据,判断一致以及删除数据三个操作是原子性

* 执行如下lua脚本:

* if redis.call('get', KEYS[1]) == ARGV[1] then

* return redis.call('del', KEYS[1])

* else

* return 0

* end

**/

//使用jedis 客户端的

/**SET key value NX PX 3000 成功返回值*/

private static final String LOCK_SUCCESS = "OK";/**表示 NX 模式*/

private static final String SET_IF_NOT_EXIST = "NX";/**单位 毫秒**/

private static final String SET_WITH_EXPIRE_TIME_PX = "PX";/**lua脚本**/

private static final String SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";/**存储随机数**/

private static final ThreadLocal local = new ThreadLocal<>();/*** 加锁*/

public static boolean lock(Jedis jedis, String key, intexpireTime) {//产生随机数

String uuid = UUID.randomUUID().toString().replaceAll("-", "");

String result=jedis.set(key, uuid, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME_PX, expireTime);if(LOCK_SUCCESS.equals(result)) {//随机数绑定线程

local.set(uuid);return true;

}return false;

}/*** 释放分布式锁*/

public static booleanunLock(Jedis jedis, String key) {

String uuid=local.get();//当前线程没有绑定uuid//直接返回

if (uuid == null || "".equals(uuid)) {return false;

}

Object result=jedis.eval(SCRIPT, Collections.singletonList(key), Collections.singletonList(uuid));if (Long.valueOf(1).equals(result)) {//解除绑定线程的随机数

local.remove();return true;

}return false;

}public static voidmain(String[] args) {

Jedis jedis= new Jedis("localhost", 6379);

jedis.auth("373616885");

jedis.select(0);final String LOCK_KEY = "LOCK_KEY";

RedisLock.lock(jedis,LOCK_KEY,5000);

RedisLock.unLock(jedis,LOCK_KEY);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值