只用Mysql搞一个分布式锁

本文讲述了在web开发中使用Mysql的GET_LOCK和RELEASE_LOCK实现分布式锁,以及Python实现方法。
摘要由CSDN通过智能技术生成

在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
  • 17
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

socratescli

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值