2

mysql加锁/解锁函数

 1 year ago
source link: https://www.jianshu.com/p/e108502d6752
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

mysql加锁/解锁函数 - 简书

mysql加锁/解锁函数

2022.08.23 10:08:57字数 328阅读 8

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

更多精彩内容,就在简书APP
"小礼物走一走,来简书关注我~"
还没有人赞赏,支持一下
总资产69共写了89.1W字获得1,609个赞共810个粉丝

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK