Ruby 数据库实现的分布式锁

807715333 · 2024年04月19日 · 最后由 hellorails 回复于 2024年05月22日 · 477 次阅读

请问下各位大佬,目前有基于数据库实现分布式锁的 gem 吗 看了下只找到了一个 redlock,基于 redis 实现的 但是项目中的版本比较旧,使用 redlock 的话需要升级 ruby 和 rails 版本,怕影响太大

require 'active_record'
require 'mutex_m'

class ScheduleLock

  def initialize
    @locked = false
    @mutex = Mutex.new
  end

  def lock(name)
    @mutex.synchronize do
      ActiveRecord::Base.transaction do
        lock = ActiveLock.find_or_create_by!(name: name)
        host_name = `hostname`.strip
        if lock.locked?
          Rails.logger.error "Lock #{name} is already locked by #{lock.host}"
          return
        else
          lock.update!(locked: true, host: host_name)
          @locked = true
        end
      end
    end
  end

  def unlock(name)
    @mutex.synchronize do
      ActiveRecord::Base.transaction do
        lock = ActiveLock.find_or_create_by!(name: name)
        if lock.locked?
          lock.update!(locked: false)
          @locked = false
        end
      end
    end
  end

  def with_lock(name)
    lock(name)
    return unless @locked

    begin
      yield
    ensure
      unlock(name)
    end

  end
end

可以自己写一个,我在自己项目里面就这样简单的基于 activerecord 做一个

使用 redis, redlock 就是用 redis 实现的,用个老版本的 redis

yfscret 回复

嗯,看主页上写的是 redis-server 必须 6.0 以后的,我项目中的 redis 有点老

crazyjacky 回复

参考下,实在不行就简单点实现了😂

crazyjacky 回复

Rails 应用基本都是多进程部署,Mutex 应该是无效的;基于数据库实现锁的话 Mutex 似乎又是多余的

需要 登录 后方可回复, 如果你还没有账号请 注册新账号