【问题标题】:Why do i get the following error? "Mysql2::Error: closed MySQL connection: SHOW TABLES"为什么我会收到以下错误? “Mysql2::Error: 关闭 MySQL 连接:SHOW TABLES”
【发布时间】:2011-12-15 20:14:50
【问题描述】:

使用 Spork、Rails3、RSpec2、Capybara 和 FactoryGirl。

在尝试执行 Capybara 测试时出现以下错误:

 Failure/Error: model = FactoryGirl.create(:model)
    ActiveRecord::StatementInvalid:
      Mysql2::Error: closed MySQL connection: SHOW TABLES

database.yml 正在使用的 MySQL 数据库已启动并正在运行。我可以使用 database.yml 中的相同设置从命令行连接到它。

测试运行良好,我试图找出测试失败的原因,然后它开始出现此错误。

我尝试关闭并重新启动数据库,但无济于事。

来自 database.yml

test:
  adapter: mysql2
  encoding: utf8
  reconnect: false
  database: mysql_app_test
  pool: 5
  username: root
  password:
  host: localhost

根据我的规范

require 'spec_helper'

describe "Model", :js => true do

  before(:each) do
    model = FactoryGirl.create(:model)
    visit model_path(model)
  end

  it "should show the button" do
    # Start the lesson
    find("#startButton")
  end
end

更新:

还需要提一下,我一直在使用 solution 3 到与非 Rack::Test 驱动程序关联的 Capybara Transactional Fixtures Issue

我已将我的解决方案放在我的 spec_helper.rb 文件中,如下所示:

Spork.prefork do
  ...
  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
  ...
end

我听说在solution 2 的评论中有类似的issues when using solution 3 with spork。我不确定这些是否是评论者提到的问题。

【问题讨论】:

  • 您是否尝试过从命令行运行 SHOW TABLES 命令?
  • 是的,我可以使用相同的用户/密码/数据库登录 Mysql 并运行 SHOW TABLES。按预期工作。
  • 我在 MySQL2 github 上看到了一个问题:github.com/brianmario/mysql2/issues/209

标签: mysql ruby-on-rails-3 rspec2 capybara factory-bot


【解决方案1】:

我想我已经弄清楚了。我无法在网上找到解决方案,因此我将在此处记录以防其他人在谷歌上搜索该错误消息。

我认为问题在于 Spork 正在缓存/保持关闭的 MySQL 连接。

这是因为上面 Solution 3 的实现位于 Spork.prefork 定义中。所以它只会在 Spork 启动时运行一次。杀死并重新启动 Spork 将暂时解决此问题。但是,如果在新的 Spork 进程中关闭另一个 MySQL 连接,该问题将再次出现。

永久修复方法是将您的 spec_helper.rb 文件中的 Solution 3 移动到同一文件中的 Spork.each_run 定义中。所以你的 spec_helper.rb 文件应该是这样的:

Spork.prefork do
  ...
  ...
end

Spork.each_run do
  ...
  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
  ...
end

这似乎对我有用。 干杯!

【讨论】:

  • 我发现只需将这部分:ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection 移动到 each_run 块就可以了(其余的可以留在 prefork 块中)
猜你喜欢
  • 1970-01-01
  • 2016-03-12
  • 2013-05-29
  • 2012-07-31
  • 1970-01-01
  • 2011-11-29
  • 2018-01-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多