redis锁

# -*- coding: utf-8 -*-

from contextlib import contextmanager
import redis
from config import REDIS_HOST, REDIS_PORT, REDIS_PASS, logger


TE_BALANCE_LOCK_CLI = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT, db=9, password=REDIS_PASS)


class TELock(object):
    """ redis做的锁 """

    def __init__(
        self,
        account_no, # 作为锁的唯一条件
        max_retries=5,  # 最大重试次数
        db_ex_time=10   # 过期时间
    ):
        self.cli = TE_BALANCE_LOCK_CLI
        self.account_no = account_no
        self.max_retries = max_retries
        self.db_ex_time = db_ex_time

    def __get_lock(self):
        delay = 1   # 重试间隔时间
        times = 0   # 重试次数
        while True:
            # 获取为1或者获取不到都视为没有锁
            if self.cli.set(
                self.account_no,
                "1",
                ex=self.db_ex_time, # 过期时间
                nx=True # nx设置为True,则只有self.account_no不存在时,当前set操作才执行
            ):
                return True
            logger.info(
                "{} is in use, {}s 后重试".format(self.account_no, delay)
            )
            times += 1
            if times > self.max_retries:
                raise Exception("wait {} balance lock too long.".format(self.account_no))
            time.sleep(delay)

    @property
    @contextmanager
    def balance_lock(self):
        self.__get_lock()
        try:
            yield self
        finally:
            self.cli.delete(self.account_no)


if __name__ == '__main__':
    import time

    with TELock("9999").balance_lock:
        print "get"
        time.sleep(1000)

        print "exit"

  

posted on 2021-08-03 11:10  哎呀!土豆  阅读(26)  评论(0编辑  收藏  举报

导航