mysql加锁/解锁函数

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加锁/解锁函数)