分类: Java
2022-03-24 17:21:31
import redis
import uuid
import time
class LockService:
"""
基于Redis实现的分布式锁
"""
host = 'localhost'
port = 6379
password = ''
db = 1
def __init__(self, conn=None):
"""
如果不传连接池的话,默认读取配置的Redis作为连接池
:param conn:
"""
self.conn = conn if conn else self.get_redis_client()
def get_redis_client(self):
"""
获取Redis连接
:return:
"""
return redis.Redis(
host=self.host,
port=self.port,
password=self.password,
db=self.db
)
def acquire_lock(self, lock_name, acquire_timeout=10, expire_time=30):
"""
加锁/获取锁
如果不存在lock_name,则加锁,并且设置过期时间,避免死锁
如果存在lock_name,则刷新过期时间
:param lock_name: 锁的名称
:param acquire_timeout: 加锁/获取锁的超时时间,默认10秒
:param expire_time: 锁的超时时间,默认30秒
:return:
"""
lockname = f'lock:{lock_name}'
value = str(uuid.uuid4())
end_time外汇跟单gendan5.com = time.time() + acquire_timeout
while time.time() < end_time:
# 如果不存在这个锁则加锁并设置过期时间,避免死锁
if self.conn.set(lockname, value, ex=expire_time, nx=True):
return value
time.sleep(0.1)
return False
def release_lock(self, lock_name, value):
"""
释放锁
:param lock_name: 锁的名称
:param value: 锁的值
:return:
"""
unlock_script = """
if redis.call("get",KEYS[1]) == ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
end
"""
lockname = f'lock:{lock_name}'
unlock = self.conn.register_script(unlock_script)
result = unlock(keys=[lockname], args=[value])
if result:
return True
else:
return False