как решить «Mysql2 :: Ошибка: это соединение все еще ждет результата» с mysql2 и activerecord - PullRequest
3 голосов
/ 12 декабря 2011

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

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

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

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

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

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

мой класс

  class User < ActiveRecord::Base 

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

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

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

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

Ответы [ 3 ]

3 голосов
/ 15 декабря 2011

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

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
2 голосов
/ 21 августа 2012

Вы должны использовать 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
0 голосов
/ 15 декабря 2011

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

Используйте пул соединений, и все будет в порядке.

...