sto sperimentando alcuni errori su un app rotaie, lungo le linee di:In quali circostanze si vorrebbe Rails da impostare non riconnettersi al MYSQL
ActiveRecord::StatementInvalid: Mysql::Error: Lost connection to MySQL server during query: SELECT * FROM `actions` WHERE (`foo`.`id` = 16)
Quello che sembra accadere è che mysql la connessione viene chiusa dopo un timeout e le guide non si accorgono fino a quando non è troppo tardi.
La remedies I findappear to be per impostare il flag riconnessione al vero in database.yaml, o per qualsiasi azione di database aggiungendo un po 'di codice in questo 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
sto messa in vendita di questa opzione over this one visible here, perché questa opzione è apparentemente non sicuro per le transazioni:
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
Tra le opzioni per evitare questo errore fastidioso, l'opzione di riconnessione nel file YAML sembra di gran lunga l'opzione più ordinata - ma sono curioso; perché non dovresti impostare questo valore come vero per impostazione predefinita nel tuo database?
Preferisco non risolvere un problema causando un carico di altri più in basso.
Grazie,
Ok ora sono totalmente confuso. Questo mi suggerisce che impostare 'reconnect' su' true' potrebbe essere dannoso, perché le transazioni che vengono annullate quando non vengono considerate sembrano una cosa negativa. Qual è la solita soluzione alternativa per evitare questo stato di cose? –
La soluzione è assicurarsi che le transazioni siano "atomiche", ovvero se si perde la connessione e si riconnette, l'intera transazione deve essere ripetuta, non solo una singola istruzione all'interno della transazione. Non sono sicuro di come funzioni in Rails, ma credo che una soluzione sarebbe quella di mettere la transazione in una stored procedure - nel codice Rails, si esegue una singola istruzione SQL per eseguire la stored procedure, quindi se si riconnette automaticamente , l'intera transazione ricomincia dall'inizio. –
OTOH, se non si stanno utilizzando le transazioni, quindi utilizzare la funzione di riconnessione automatica è probabilmente meno di un problema. –