Первичные и реплицируемые базы данных на Rails 4

#mysql #ruby-on-rails #ruby #ruby-on-rails-4 #mysql2

#mysql #ruby-on-rails #ruby #ruby-on-rails-4 #mysql2

Вопрос:

Я реализую на Rails 4 первичные / реплицируемые базы данных, простые REST реализации, такие как использование a POST для постоянного использования первичных и GET для реплики, в этом случае не будут работать, поскольку приложение потенциально может изменять записи по любому заданному запросу (пометить уведомление как прочитанное, установить время последнего входа пользователя,и т.д.).

Я думал о переопределении ActiveRecord методов сохранения, подобных этому:

 class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  def save(*)
    write_only { super }
  end

  def save!(*)
    write_only { super }
  end

  def delete
    write_only { super }
  end

  def destroy
    write_only { super }
  end

  def becomes(klass)
    write_only { super(klass) }
  end

  def becomes!(klass)
    write_only { super(klass) }
  end

  def update_columns(attributes)
    write_only { super(attributes) }
  end

  private

  def write_only
    begin
      ActiveRecord::Base.establish_connection("#{Rails.env}_primary".to_sym)
      yield
    ensure
      ActiveRecord::Base.establish_connection("#{Rails.env}_replica".to_sym)
    end
  end
end

 

Из этого каждая модель просто наследует от ApplicationRecord like:

 class User < ApplicationRecord
  ...
end
 

Эта реализация отлично работает в большинстве случаев (особенно в консоли rails никогда не обнаруживалась проблема), однако я обнаружил, что в некоторых ситуациях я получаю ошибки, такие как: Rails -- Exception: ActiveRecord::StatementInvalid: Mysql2::Error: MySQL client is not connected: ROLLBACK , особенно при использовании create , create! (это не всегда так, кстати)

есть ли лучший способ?

Примечание: я не переопределял create методы, поскольку они вызываются внутренне save , то же самое относится и к другим, однако я пробовал, и приложение по-прежнему не работает.

Комментарии:

1. Я был бы очень осторожен с исправлением этих методов с помощью monkey. Почему вы не используете защищенный от пуль камень, такой как Makara ( github.com/instacart/makara )?

2. 1 к предложению @ChristianBruckmayer. Ответ, объясняющий реализацию, как вы спрашиваете, может быть образовательным, но использование драгоценного камня было бы лучшим выбором. Это еще один популярный вариант github.com/thiagopradi/octopus

3. Tnx @ChristianBruckmayer не знал, что этот камень попробует это

4. Наш Ruby on Rails исчерпал свой ресурс и не поддерживается. Вместо того, чтобы добавлять такую сложную низкоуровневую функцию в старое приложение Rails, я бы сосредоточился на обновлении приложения до последней версии Ruby on Rails. Помимо функции безопасности, улучшенной скорости и большей функциональности, Ruby on Rails 6.1 имеет встроенную поддержку нескольких баз данных.