Redis分布式锁释放锁是否必须用lua脚本?

无lua脚本释放锁:

java 复制代码
public void unlock(String key, String uniqueValue) {
	String value =redisDao.getString(key);
	if (value != null && value.equals(uniqueValue))
		redisDao.delete(key);
}

使用lua脚本释放锁:

java 复制代码
	// LUA脚本 -> 分布式锁解锁原子操作脚本
    private static final String LUA_SCRIPT =
            "if redis.call('get',KEYS[1]) == ARGV[1] then" +
                    " return redis.call('del',KEYS[1]) " +
                    "else" +
                    " return 0 " +
                    "end";
    // lockId 一个不重复id -> 区分不同客户端
    public boolean unlock(String lockId) {
        Jedis client = jedisPool.getResource();
        try {
            Object result = client.eval(LUA_SCRIPT, Arrays.asList(LOCK_KEY), Arrays.asList(lockId));
            if (result != null && "1".equalsIgnoreCase(result.toString())) {
                return ture;
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return false;
    }

在释放锁的时候,如果没用原子操作,那么取值、比较、删除是三步操作。

假设现在是线程A在执行当前的动作。如果线程A取值之后,删除操作之前,key正好过期了,那么锁就自动释放了。这时,又被另外一个线程B获取了锁,那么在删除操作时,就会把线程B的锁给删除掉。如果这时线程B还在执行中,因为线程B的锁被线程A给删除掉了,那么其他的线程C也就可以获取到锁了。这样,其实临界区就有多个线程在运行了。

相关推荐
a程序小傲11 小时前
得物Java面试被问:流批一体架构的实现和状态管理
java·开发语言·数据库·redis·缓存·面试·架构
【赫兹威客】浩哥12 小时前
【赫兹威客】完全分布式ZooKeeper测试教程
分布式·zookeeper·云原生
一晌小贪欢12 小时前
Python 魔术方法实战:深度解析 Queue 模块的模块化设计与实现
开发语言·分布式·爬虫·python·python爬虫·爬虫分布式
【赫兹威客】浩哥12 小时前
【赫兹威客】伪分布式Flink测试教程
大数据·分布式·flink
小北方城市网13 小时前
Spring Cloud Gateway 生产级微内核架构设计与可插拔过滤器开发
java·大数据·linux·运维·spring boot·redis·分布式
(;_;)(╥ω╥`)13 小时前
kafka原理剖析(一)
分布式·kafka·linq
码农水水14 小时前
京东Java面试被问:分布式会话的一致性和容灾方案
java·开发语言·数据库·分布式·mysql·面试·职场和发展
【赫兹威客】浩哥14 小时前
【赫兹威客】完全分布式Spark测试教程
大数据·分布式·spark
是三好14 小时前
redis
数据库·redis·缓存
成为你的宁宁14 小时前
【RabbitMQ 集群企业级实战:RabbitMQ 特性、存储、工作模式解析与普通集群搭建及仲裁队列搭建企业级配置】
分布式·rabbitmq