【问题标题】:How to easily patch several ActiveRecord models against deadlocks如何轻松修补多个 ActiveRecord 模型以防止死锁
【发布时间】:2020-06-25 23:47:08
【问题描述】:

所以我维护了一个包含 150 多个数据库表的 Rails 应用程序。我们在几个地方遇到了僵局。

阅读这篇文章https://hackernoon.com/troubleshooting-and-avoiding-deadlocks-mysql-rails-766913f3cfbc 并更好地理解不同的情况。似乎我们拥有的一种常见模式是由于唯一索引在并发锁上相互等待。

所以我正在寻找一种方法来在模型中说它不应该尝试同时插入两个,因为 MySQL 会锁定表。我希望它尽可能简单。

class BingoCard < ActiveRecord::Base
  protect_table_locks
end

这将使用 Redis 基础锁来环绕创建操作

我已经研究过这个答案的想法。 Mutex for ActiveRecord Model

我计划在获得答案后发布自己的答案。

【问题讨论】:

    标签: ruby-on-rails activerecord rails-activerecord deadlock database-deadlocks


    【解决方案1】:

    这是我的实施草案。 如果有足够的兴趣,我会把它变成宝石

    # frozen_string_literal: true
    
    module ActiveRecord
      module PersistenceRedisLock
    
        private
    
        def _create_record
          _lock_manager.lock(_locked_resource_id, _lock_duration) do |_lock_info|
            super
          end
        end
    
        def _locked_resource_id
          #TODO: make it a configurable option
          "PersistenceRedisLock#{self.class.table_name}"
        end
    
        def _lock_duration
          #TODO: make it a configurable option
          10.seconds # Maybe too long of a default, but this is a proof of concept for now
        end
    
        def _lock_manager
          @@_lock_manager ||= Redlock::Client.new [Ph::Redis.redis_url_for(:red_locks)]
        end
      end
    
      class Base
        def self.protect_table_locks
          self.prepend PersistenceRedisLock
        end
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多