使用Redis实现分布式可重入锁

本文介绍了如何在分布式环境中利用Redis的SET命令构建可重入的锁,并讨论了使用线程局部变量来跟踪锁的持有次数以实现可重入性。同时提醒注意Redis分布式锁的超时问题,建议避免用于长时间任务,对于这类任务可以考虑使用数据库的乐观锁。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在分布式应用中经常需要用到分布式锁。
redis使用set命令来实现分布式锁
SET key value [EX seconds] [PX milliseconds] [NX|XX]
直接使用该命令构建的redis分布式锁是不像jdk的reentrantlock具有可重入性的,使用线程的ThreadLocal变量存储当前持有锁的计数,可以实现redis分布式锁的可重入性。
另外Redis分布式锁有超时的问题,不要用于耗时较长的任务.如果真的有耗时较长的任务需要锁,建议使用数据库的乐观锁来解决。

import redis
import threading

HOST = '127.0.0.1'
PORT = '6379'
PASSWORD = ''

pool = redis.ConnectionPool(host=HOST, port=PORT, password=PASSWORD, max_connections=1024)
conn = redis.Redis(connection_pool=pool)

locks = threading.local()
locks.redis = {}


def key_for(user_id):
    return "account_{}".format(user_id)


def _lock(client, key):
    print("redis lock ")
    return bool(client.set(name=key, value="1", nx=True, ex=5))


def _unlock(client, key):
    print("redis un lock")
    client.delete(key)


def lock(client, user_id):
    key = key_for(user_id)
    if key in locks.redis:
        locks.redis[key] += 1
        return True
    ok = _lock(client, key)
    if not ok:
        return False
    locks.redis[key] = 1
    return True


def unlock(client, user_id):
    key = key_for(user_id)
    if key in locks.redis:
        locks.redis[key] -= 1
        if locks.redis[key] <= 0:
            del locks.redis[key]
            _unlock(client, key)
        return True
    return False


print(lock(conn, "codehole"))
print(lock(conn, "codehole"))
print(unlock(conn, "codehole"))
print(unlock(conn, "codehole"))

输出
输出
redis lock
True
True
unlock
True
redis un lock
True

参考资料<<Redis深度历险 核心原理与应用实践>>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值