Files
Django/utils/redis_lock.py
2026-06-14 00:24:53 +08:00

58 lines
1.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import uuid
import logging
from django.conf import settings
from django.core.cache import cache
logger = logging.getLogger(__name__)
# Redis客户端延迟初始化
_redis_client = None
def _get_redis_client():
global _redis_client
if _redis_client is None:
import redis
_redis_client = redis.Redis(
host=settings.REDIS_HOST,
port=settings.REDIS_PORT,
password=settings.REDIS_PASSWORD,
db=settings.REDIS_DB_CELERY,
decode_responses=True,
)
return _redis_client
def acquire_lock(lock_key, timeout=10):
"""获取分布式锁返回锁标识符失败返回None"""
client = _get_redis_client()
identifier = str(uuid.uuid4())
result = client.set(lock_key, identifier, nx=True, ex=timeout)
if result:
logger.debug(f"获取锁成功: {lock_key}, 标识: {identifier}")
return identifier
return None
def release_lock(lock_key, identifier):
"""释放分布式锁(仅当标识符匹配时才释放)"""
if identifier is None:
return False
client = _get_redis_client()
lua_script = """
if redis.call('get', KEYS[1]) == ARGV[1] then
return redis.call('del', KEYS[1])
else
return 0
end
"""
try:
result = client.eval(lua_script, 1, lock_key, identifier)
if result:
logger.debug(f"释放锁成功: {lock_key}")
else:
logger.warning(f"释放锁失败(标识不匹配或锁已过期): {lock_key}")
return bool(result)
except Exception as e:
logger.error(f"释放锁异常: {lock_key}, 错误: {e}")
return False