只用Mysql搞一个分布式锁

在web开发中,分布式的锁的应用场景甚多,我们可以通过分布式锁来进行一些仅依赖于数据库的事务很难直接保证原子性的操作,比如多种不同数据源的访问,网络通信等等。多数情况下我们会使用memcache的add, redis中在set中指定nx参数等来完成。

下面介绍一个仅依赖Mysql来完成分布式锁的方式,如果项目比较小且主要使用的数据库是Mysql,那么就不需要引入额外的架构上的依赖了。

这里的方法就是通过Mysql的GET_LOCK函数和RELEASE_LOCK函数来完成的。我们可以通过GET_LOCK(lock_key, timeout)函数来创建一个key:

SELECT GET_LOCK('user_id_XXXX', 10)

除了获取到lock_key的进程,其他进程就无法进入被这个锁锁住的代码逻辑了。之后,在同一个db session中,可以再通过RELEASE_LOCK(lock_key)来释放这个lock_key:

SELECT RELEASE_LOCK('user_id_XXXX')

被释放的lock_key就可以被别的进程获取了。

我写了一个python的例子,可以看一下

class DbLock(object):
    def __init__(self, key, connection, timeout=5):
        '''
        key: lock key.
        connection: a db connection object.
        '''
        self.key = key
        self.connection = connection
        self.timeout = timeout
        self.cursor = None

    def __enter__(self):
        self.cursor = self.connection.cursor()
        self.cursor.execute("SELECT GET_LOCK(%s, %s)",
                            [self.key, self.timeout])
        result, = self.cursor.fetchone()
        if result != 1:
            raise Exception("DbLock %s error, timeout %s, returned %s."\
                            % (self.key, self.timeout, result))

    def __exit__(self, exc_type, exc_value, traceback):
        self.cursor.execute("SELECT RELEASE_LOCK(%s)",
                            [self.key])
        self.cursor.close()
        if exc_type is not None:
            pass
            # deal with error

这样在实际的代码中,就可以通过如下方式来使用这个lock了(我们假设是django的数据库connection对象):

from django.db import connection

with DbLock(key, connection, 5):
    # your own code

相关推荐

  1. Mysql一个分布式

    2024-01-21 08:40:06       55 阅读
  2. Mysql实现分布式

    2024-01-21 08:40:06       43 阅读
  3. 如何实现一个分布式

    2024-01-21 08:40:06       21 阅读
  4. MySQL

    2024-01-21 08:40:06       58 阅读
  5. 一个产生Redis分布式的场景。

    2024-01-21 08:40:06       19 阅读
  6. redis分布式到底怎么

    2024-01-21 08:40:06       38 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-21 08:40:06       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-21 08:40:06       106 阅读
  3. 在Django里面运行非项目文件

    2024-01-21 08:40:06       87 阅读
  4. Python语言-面向对象

    2024-01-21 08:40:06       96 阅读

热门阅读

  1. C语言:函数指针的使用

    2024-01-21 08:40:06       57 阅读
  2. 网络卡问题排查手段

    2024-01-21 08:40:06       59 阅读
  3. [Linux] Ubuntu install Miniconda

    2024-01-21 08:40:06       63 阅读
  4. 科普大语言模型中的Embedding技术

    2024-01-21 08:40:06       54 阅读
  5. MySQL死锁场景与应对方案

    2024-01-21 08:40:06       59 阅读
  6. C#设计模式教程(10):装饰器模式

    2024-01-21 08:40:06       51 阅读
  7. Webpack5入门到原理15:提取 Css 成单独文件

    2024-01-21 08:40:06       53 阅读
  8. vue对axios进行二次封装

    2024-01-21 08:40:06       50 阅读