Sinatra 在 Sinatra 里用 ActiveRecord 经常遇到数据库连接超时?

esseak · 2014年02月27日 · 最后由 esseak 回复于 2014年02月28日 · 9243 次阅读

代码很简单,Temp2 表中有一列 man_id 是空的,首页 index.erb 会选出一条然后人工用 select 选一个 bid 做对应 save 后又转到 index 去,但是经常用着用着就报下面错误。是不是要关闭连接?

ActiveRecord::ConnectionTimeoutError - could not obtain a database connection within 5.000 seconds (waited 5.000 seconds):

大概代码如下

ActiveRecord::Base.establish_connection(
    :adapter  => 'mysql2',
    :database => 'mandb',   #oracle service name
    :username => 'root',
    :password => '')
get '/' do
   @t_man = Temp2.where("man_id is NULL").first
   if @t_man.nil?
     erb :success
   else
     erb :index
   end
end

post '/save' do
  tid = params['tid']
  bid = params['bid']
  if bid==-1
    redirect to('/')
  end
  t =  Temp2.where("tid=#{tid}").first
  if !t.nil?
    t.man_id = bid
    t.save
  end
  redirect to('/')
end

设置一下 pool 看看:

ActiveRecord::Base.establish_connection(
    :adapter  => 'mysql2',
    :database => 'mandb',   #oracle service name
    :username => 'root',
    :password => '',
    :pool => 5
)

设置 断开重连:reconnect: true 试试

下面是我修改的代码,还是会出现问题

ActiveRecord::ConnectionTimeoutError - could not obtain a database connection within 5.000 seconds (waited 5.001 seconds):
ActiveRecord::Base.establish_connection(
    :adapter  => 'mysql2',
    :database => 'mandb',   #oracle service name
    :username => 'root',
    :password => '',
    :pool => 5,
    :reconnect =>true)

@esseak 刚才试了一下你的 代码 没有问题。

@meeasyhappy 谢谢你的回复,不定期会出现的,不是必现,大概一直提交个 100 多条记录就会出现问题,很奇怪

#6 楼 @esseak 需要加一个 after 的过滤器

after do
  ActiveRecord::Base.connection.close
end

@esseak 当连续访问的时候 确实会出现上面的问题;解决方法: 在文件中添加一下 几行

after do
  ActiveRecord::Base.connection.close
end

大致原因 分析:(我用的 server 是 thin) :

thin 用两个 thread 处理请求,一个 thread 负责连接 mysql 处理逻辑,另一个 负责 断开连接。 然后在每次处理完请求 之后断开,连接 就 ok 了。

用 ActiveRecord 还需要手动关闭链接的么。。。那我还是推荐上 sequel 好了,至少部署在公司的 api 服务器上没见过有问题

多线程的情况下,每次查询完要把连接收回ActiveRecord::ConnectionAdapters::ConnectionManagement use 这个 middleware 应该就可以了

@meeasyhappy @jjym @qichunren 谢谢了 是要关闭连接。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号