ruby oracle-睡眠后增强卡住连接

时间:2013-04-29 03:33:20

标签: ruby oracle activerecord sinatra

感谢您的关注。在一段空闲时间之后,我们对卡住的连接感到有些困惑,并且会感激任何帮助或尝试的事情。

我们在jruby 1.7.2上的Sinatra应用程序中使用了带有ojdbc6.jar的activerecord-oracle_enhanced-adapter v1.4.1。我的控制器调用一个帮助器类方法并返回一个json字符串。辅助类方法只是在Oracle数据库中查询数据。代码如下所示:

class App < Sinatra::Base
  get '/customer/:id_number' do |id_number|
    MyHelper.customer(id_number).to_json
  end
end

class MyHelper
  @dbconfig = YAML.load_file("../config/database.yml")
  @dbenv = @dbconfig["#{settings.environment}"]

  puts "establish_connection"
  ActiveRecord::Base.establish_connection(@dbenv)

  def self.customer(id_number)
    begin
      query = <<-SQL
        SELECT * FROM customer WHERE cust_id = '#{id_number}'
      SQL
      puts 1
      ActiveRecord::Base.connection.exec_query(query)
      puts 2
    rescue => e
      puts 3
      puts e.message
    ensure
      puts 4
      ActiveRecord::Base.clear_active_connections!
      puts 5
    end
   end
end

我们有一个shell脚本,它会击中控制器50次,睡眠2小时并重复。我们可以在开头看到一个对establish_connection的调用(预期)。我们没想到的是,在睡眠之后,与数据库的第一次连接总是被卡住。我们在日志中看到的只是“1”。 15分钟后,客户端超时并再次呼叫控制器。第二次调用似乎具有“唤醒”连接池的效果,因为它总是恢复线程1,因此我们看到“2”,“4”和“5”。同时,我们还会看到线程2的日志消息:“1”,“2”,“4”和“5”。我们知道,因为实际代码将Thread.current.object_id打印为消息的一部分。

我们尝试添加ActiveRecord :: Base.connection.verify!就在exec_query之前,但只会将卡住的调用转移到验证行。

我们是否正确使用了适配器?还有其他我们可以试试的吗?

1 个答案:

答案 0 :(得分:0)

我使用事件机器和oracle适配器实现了一个解决方案,我是的,错误就在那里,唯一的方法是修复&#34;这个问题迫使我的应用程序重新连接到oracle,所以这是我的例子

unless ActiveRecord::Base.connection.active?
  begin
    ActiveRecord::Base.connection.reconnect!
  rescue => e
    EchoServer.log e
  end
end

所以,在每次Active Record连接之前,我都会询问连接是否仍然存在,如果没有,我尝试手动重新连接,当时它正在工作,但是,这不是最优的解决方案,但是...... ..希望它会起作用

PD: 有一些与此错误相关的问题,其中有几个:

https://github.com/rsim/oracle-enhanced/issues/420

Does reaper work with oracle-enhanced adapter (OCI) to reap out idle connections?