实现
class DisLockService:
DEL_SCRIPT = '''
if redis.call('get', KEYS[1]) == ARGV[1] then
return redis.call('del', KEYS[1])
else
return 0
end
'''
@staticmethod
def tryLock(redisClient, lockKey, lockVal="1", px=5000):
return redisClient.set(lockKey, lockVal, px=px, nx=True)
@staticmethod
def unLock(redisClient, lockKey, lockVal="1"):
return redisClient.eval(DisLockService.DEL_SCRIPT, 1, lockKey, lockVal)
用法
nowTs = int(time.time())
lockVal = str(nowTs)
lockKey = 'test'
if DisLockService.tryLock(redisClient, lockKey, lockVal):
try:
# 添加自己的业务
pass
finally:
DisLockService.unLock(redisClient, finishPkLockKey, nowTsStr)
改进
class DisLockService(object):
DEL_SCRIPT = '''
if redis.call('get', KEYS[1]) == ARGV[1] then
return redis.call('del', KEYS[1])
else
return 0
end
'''
def __init__(self, redisClient, lockKey, lockVal, ttl=5000):
'''
:param redisClient:
:param lockKey:
:param lockVal:
:param ttl: 单位 毫秒
:param args:
'''
self.redisClient = redisClient
self.lockKey = lockKey
self.lockVal = lockVal
self.ttl = ttl
def __enter__(self):
ret = redisClient.set(self.lockKey, self.lockVal, px=self.ttl, nx=True)
if not ret:
raise Exception("accquire lock failed")
return self
def __exit__(self, etype, evalue, tb):
redisClient.eval(DisLockService.DEL_SCRIPT, 1, self.lockKey, self.lockVal)
用法
with DisLockService(redisClient, 'test', '1'):
print 'xx'
with DisLockService(redisClient, 'test', '1'):
print 'xx'