Chr*_*ams 13 mysql ruby-on-rails
我在rails应用程序上遇到了一些错误,其中包括:
ActiveRecord::StatementInvalid: Mysql::Error: Lost connection to MySQL server during query: SELECT * FROM `actions` WHERE (`foo`.`id` = 16)
Run Code Online (Sandbox Code Playgroud)
似乎正在发生的事情是mysql连接在超时后被关闭,并且rails没有注意到它为时已晚.
我找到 的补救措施似乎是在database.yaml中将reconnect标志设置为true,或者对于添加一些代码的任何数据库操作:
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
Run Code Online (Sandbox Code Playgroud)
我在此处列出了此选项,因为此选项显然对交易不安全:
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
Run Code Online (Sandbox Code Playgroud)
在避免这个烦人的错误的选项中,yaml文件中的重新连接选项似乎是最整洁的选项 - 但我很好奇; 为什么你不会在数据库中默认将此值设置为true?
我宁愿不通过引起其他人的加载来解决一个问题.
谢谢,
Mik*_*oss 13
正如您在问题中指出的那样,自动重新连接(如果在每个语句级别完成)的一个可能的副作用是它不是事务安全的.
MySQL 文档实际上明确指出自动重新连接功能会影响事务:
回滚任何活动事务并重置自动提交模式.
未写入处理此问题的应用程序很容易破解.该文档还列出了由自动重新连接功能引起的许多其他副作用,所有这些都可能导致未写入的应用程序预期行为无法正常运行或失败.
此外,如果与数据库的连接突然丢失,服务器可能无法正确释放连接所持有的锁,因此听起来应用程序在某些情况下可能会死锁:
如果连接断开,则如果服务器尚未检测到客户端不再连接,则与服务器端连接关联的会话可能仍在运行.在这种情况下,原始连接所持有的任何锁仍然属于该会话,因此您可能希望通过调用mysql_kill()来终止它.
从Rails 2.3发行说明(强调我的):
4.8重新连接MySQL连接
MySQL在其连接中支持重新连接标志 - 如果设置为true,则客户端将尝试重新连接到服务器,然后在连接丢失的情况下放弃.您现在可以
reconnect = true在database.yml中设置MySQL连接,以便从Rails应用程序中获取此行为.默认值为false,因此现有应用程序的行为不会更改.
| 归档时间: |
|
| 查看次数: |
5919 次 |
| 最近记录: |