美文网首页
mysql加锁/解锁函数

mysql加锁/解锁函数

作者: 零一间 | 来源:发表于2022-08-23 18:08 被阅读0次

    mysql加锁/解锁函数

    get_lock(str,timeout);

    得到一个锁,锁名为str,持续时间为timeout。可以使用release_lock()或连接断开(正常非正常)解锁

    若加锁成功:返回1
    操作超时未:返回0
    发生错误:返回去NULL

    release_lock(str)

    解开被get_lock加锁的锁
    若锁被解开:返回1
    若该线程尚未被创建锁:返回0(此时锁还没有解开)
    若命名的锁不存在:返回NULL
    若该锁从未被get_lock()的调用获取,或锁已经被提前解开:则该锁不存在

    is_free_lock(str);

    检查名为str的锁是否可以使用(没有被封锁)
    若该锁可以使用(没有人在用这个锁):返回1
    若锁正在被使用:返回0
    出现错误:返回NULL
    is_used_lock(str); //检查锁名为str的锁是否正在被使用(被封锁)
    被封锁:返回使用该锁用户的客户端的连接标识符(connection ID)
    否则:返回NULL

    mysql分布式锁实现

    加锁、释放锁必须在同一个session

    示例

    #!/usr/bin/env python3
    # -*- coding:utf-8 -*-
    
    import logging, time
    import pymysql
    
    
    class MysqLock:
        def __init__(self, db):
            self.db = db
    
        def _execute(self, sql):
            cursor = self.db.cursor()
            try:
                ret = None
                cursor.execute(sql)
                if cursor.rowcount != 1:
                    logging.error("Multiple rows returned in mysql lock function.")
                    ret = None
                else:
                    ret = cursor.fetchone()
                cursor.close()
                return ret
            except Exception as ex:
                logging.error("Execute sql \"%s\" failed! Exception: %s", sql, str(ex))
                cursor.close()
                return None
    
        def get_lock(self, lockstr, timeout):
            """
            设置锁
            """
            sql = "SELECT GET_LOCK('%s', %s)" % (lockstr, timeout)
            ret = self._execute(sql)
    
            if ret[0] == 0:
                logging.debug("Another client has previously locked '%s'.", lockstr)
                return False
            elif ret[0] == 1:
                logging.debug("The lock '%s' was obtained successfully.", lockstr)
                return True
            else:
                logging.error("Error occurred!")
                return None
    
        def release_lock(self, lockstr):
            """
            释放锁
            """
            sql = "SELECT RELEASE_LOCK('%s')" % lockstr
            ret = self._execute(sql)
            if ret[0] == 0:
                # 线程尚未被创建锁
                logging.debug("The lock '%s' the lock is not released(the lock was not established by this thread).",
                              lockstr)
                return False
            elif ret[0] == 1:
                # 锁被解开
                logging.debug("The lock '%s' the lock was released.", lockstr)
                return True
            else:
                # 锁不存在
                logging.error("The lock '%s' did not exist.", lockstr)
                return None
            # Init logging
    
    
    def init_logging():
        sh = logging.StreamHandler()
        logger = logging.getLogger()
        logger.setLevel(logging.DEBUG)
        formatter = logging.Formatter('%(asctime)s -%(module)s:%(filename)s-L%(lineno)d-%(levelname)s: %(message)s')
        sh.setFormatter(formatter)
        logger.addHandler(sh)
        logging.info("Current log level is : %s", logging.getLevelName(logger.getEffectiveLevel()))
    
    
    def main():
        init_logging()
        db = pymysql.connect(host='localhost', user='root', passwd='123456')
        lock_name = 'queue'
    
        lock = MysqLock(db)
        ret = lock.get_lock(lock_name, 10)
        if not ret:
            logging.error("Can't get lock! exit!")
            quit()
        time.sleep(10)
        logging.info("You can do some synchronization work across processes!")
    
        # TODO
        # 可以处理一些事情
        lock.release_lock(lock_name)
    
    
    if __name__ == "__main__":
        main()
    
    

    参考:

    https://www.jb51.net/article/51947.htm

    https://dev.mysql.com/doc/refman/5.7/en/locking-functions.html

    相关文章

      网友评论

          本文标题:mysql加锁/解锁函数

          本文链接:https://www.haomeiwen.com/subject/dnmggrtx.html