que estoy experimentando algunos errores en una aplicación de rieles, a lo largo de las líneas de:¿En qué circunstancias le gustaría rieles para ser configurado para no volver a conectar a MySQL
ActiveRecord::StatementInvalid: Mysql::Error: Lost connection to MySQL server during query: SELECT * FROM `actions` WHERE (`foo`.`id` = 16)
Lo que parece estar sucediendo es que MySQL la conexión se cierra después de un tiempo de espera, y los rieles no se notan hasta que es demasiado tarde.
El remedies I findappear to be para establecer el indicador de reconexión en true en database.yaml, o por cualquier acción de base de datos añadiendo un poco de código de este modo:
def some_database_operation
begin
Account.find(1)
# or some other database operations here...
rescue ActiveRecord::StatementInvalid
ActiveRecord::Base.connection.reconnect!
unless @already_retried
@already_retried = true
retry
end
raise
else
@already_retried = false
end
end
end
estoy lista over this one visible here esta opción, ya que esta opción es aparentemente inseguro para las transacciones:
ActiveRecord::ConnectionAdapters::MysqlAdapter.module_eval do
def execute_with_retry_once(sql, name = nil)
retried = false
begin
execute_without_retry_once(sql, name)
rescue ActiveRecord::StatementInvalid => exception
ActiveRecord::Base.logger.info "#{exception}, retried? #{retried}"
# Our database connection has gone away, reconnect and retry this method
reconnect!
unless retried
retried = true
retry
end
end
end
alias_method_chain :execute, :retry_once
end
de las opciones para evitar este error molesto, la opción de reconexión en el archivo yaml parece por el momento la opción más limpio - pero tengo curiosidad; ¿Por qué no establecería este valor como verdadero de forma predeterminada en su base de datos?
Prefiero no resolver un problema causando una carga de otros más adelante en la línea.
Gracias,
Bien, ahora estoy totalmente confundido. Esto me sugiere que configurar 'reconectar' a 'verdadero' podría ser perjudicial, porque las transacciones que se retrotraen cuando no se supone suenan como algo malo. ¿Cuál es la solución habitual para evitar este estado de cosas? –
La solución es asegurarse de que sus transacciones sean "atómicas", es decir, si pierde la conexión y se vuelve a conectar, se debe volver a intentar toda la transacción, no solo una declaración única dentro de la transacción. No estoy seguro de cómo funciona esto en Rails, pero supongo que una solución sería poner la transacción en un procedimiento almacenado: en el código de Rails, se ejecuta una única instrucción SQL para ejecutar el procedimiento almacenado, y luego si se reconecta automáticamente. , toda la transacción comienza desde el principio. –
OTOH, si no está usando transacciones, entonces usar la función de reconexión automática probablemente sea un problema menor. –