Как решить "Mysql2:: Ошибка: это соединение все еще ждет результата" с mysql2 и activerecord

Не дублируйте этот вопрос с тем же названием

Я использую activerecord с mysql2, и я разрабатываю для обработки 10 запросов к одной и той же модели / классу activerecord одновременно. Обратите внимание, что я использую строгую activerecord и не использую запросы MySQL напрямую.

Я получаю звонки в Синатре, а затем использую activerecord для получения данных из БД.

Я не хочу блокировать вызовы, поэтому я использовал mysql2 и не хочу использовать em-synchrony.

Но теперь я получаю следующее сообщение "Mysql2::Error: это соединение все еще ожидает результата, попробуйте еще раз, когда у вас будет результат:" при последующих одновременных вызовах.

Я не устанавливаю связь с пулом =10

мои занятия

  class User < ActiveRecord::Base 

и мой код для вызова user.find(: все,: условия => ["id=?", идентификатор пользователя])

В документе mysql2 сказано: "Чтобы использовать драйвер ActiveRecord (с рельсами или без них), все, что вам нужно сделать, это установить этот гем и установить адаптер в вашем database.yml на"mysql2". Это было легко, правда?:)"

И это именно то, что я сделал, когда я перешел с mysql на mysql2.

Почему я получаю эту ошибку.

3 ответа

Вот полностью рабочий пример:

require 'rubygems'
gem 'activerecord', '~> 3.1.0'
gem 'sinatra',      '~> 1.3.1'
gem 'mysql2',       '~> 0.3.11'

require 'active_record'
require 'sinatra/base'
require 'mysql2'

# thin use the eventmachine thread pool
# you should have at least one connection per thread
# or you can expect errors
EM::threadpool_size = 10

# connect to the database
ActiveRecord::Base.establish_connection(
    :adapter => "mysql2",
    :database => "test",
    :username => "root",
    :encoding => 'utf8',
    # number of connections openened to the database
    :pool => 10
  )

class App < Sinatra::Base  
  get '/db' do
    ActiveRecord::Base.connection.execute("SELECT SLEEP(1)")
  end
end

run App

чтобы запустить его, сохраните файл как "config.ru" и запустите его с помощью thin в многопоточном режиме:

thin start -e production --threaded

Вы можете использовать ab, чтобы проверить, что все работает, я использовал инструмент под названием siege:

siege -c 10 -r 1 http://localhost:3000/db

Вы должны использовать ConnectionPool... Каким-то образом у вас есть 2 соединения в состоянии гонки.

Я не использую Sinatra, я использую Rails, но у меня была та же проблема, и я решил ее так:

#  class ActiveRecord::Base
#   mattr_accessor :shared_connection
#   @@shared_connection = nil
# 
#   def self.connection
#     @@shared_connection || retrieve_connection
#   end
# end
# 
# ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection

class ActiveRecord::Base
  mattr_accessor :shared_connection
  @@shared_connection = nil

  def self.connection
    @@shared_connection || ConnectionPool::Wrapper.new(:size => 1) { retrieve_connection }
  end
end

ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection

Вы должны использовать пул соединений. mysql2 позволяет запросам быть асинхронными, но вы все равно можете отправлять только один запрос за один раз в MySQL через одно соединение. Если вы отправляете несколько запросов по одному соединению, вы получите сообщение с ожиданием результатов.

Используйте пул соединений, и у вас все будет хорошо.

Другие вопросы по тегам