分布式锁-Redis方案

#!/usr/bin/env python
# coding=utf-8
 
import time
import redis
 
class RedisLock(object):
    def __init__(self, key):
        self.rdcon = redis.Redis(host=‘‘, port=6379, password="", db=1)
        self._lock = 0
        self.lock_key = "%s_dynamic_test" % key
 
    @staticmethod
    def get_lock(cls, timeout=10):
        while cls._lock != 1:
            timestamp = time.time() + timeout + 1
            cls._lock = cls.rdcon.setnx(cls.lock_key, timestamp)
       # 注意下方括号的范围
            if cls._lock == 1 or (time.time() > cls.rdcon.get(cls.lock_key) and time.time() > cls.rdcon.getset(cls.lock_key, timestamp)):
                print "get lock"
                break
            else:
                time.sleep(0.3)
 
    @staticmethod
    def release(cls):
        if time.time() < cls.rdcon.get(cls.lock_key):
            print "release lock"
            cls.rdcon.delete(cls.lock_key)
 
def deco(cls):
    def _deco(func):
        def __deco(*args, **kwargs):
            print "before %s called [%s]."%(func.__name__, cls)
            cls.get_lock(cls)
            try:
                return func(*args, **kwargs)
            finally:
                cls.release(cls)
        return __deco
    return _deco
 
@deco(RedisLock("112233"))
def myfunc():
    print "myfunc() called."
    time.sleep(20)
 
 
if __name__ == "__main__":
    myfunc()

eg2:

import redis
import time, datetime


def acquire_lock(conn, lockname, identifier, expire=10):
    if conn.setnx(lockname, identifier):
        conn.expire(lockname, expire)
        return identifier
    elif not conn.ttl(lockname):
        conn.expire(lockname, expire)

    return False


def release_lock(conn, lockname, identifier):
    pipe = conn.pipeline(True)
    while True:
        try:
            pipe.watch(lockname)
            if pipe.get(lockname) == identifier:
                pipe.multi()
                pipe.delete(lockname)
                pipe.execute()
                return True
            pipe.unwatch()
            break
        except redis.exceptions.WatchError:
            pass

    # we lost the lock
    return False


conn = redis.Redis(host=‘localhost‘, port=6379, db=0)

# 1 identifier
# 2 False
# 11 True
# 22 False
# 33 barx2
# 44 True

ret = acquire_lock(conn, "lockname", "identifier", 3)
print "1", ret
ret = acquire_lock(conn, "lockname", "identifier", 3)
print "2", ret
ret = release_lock(conn, "lockname", "identifier")
print "11", ret
ret = release_lock(conn, "lockname", "identifier")
print "22", ret

ret = acquire_lock(conn, "footest", "bartest", 10)
print "33", ret