2017-03-16 108 views
0

在我的代碼中,我在程序開始時打開DB並將db變量傳遞給其他方法。我認爲這很愚蠢,不對。但我該怎麼辦?我應該在每種方法中打開數據庫連接嗎?但這種方式也看起來不正確...而且我有很多錯誤:DB::ConnectionRefused, DB::PoolTimeout, DB::PoolRetryAttemptsExceeded 因此,我的代碼有問題。使用DB和DB連接池的正確方式是什麼?

def main_meth 
db = DB.open("postgres://[email protected]:5432/bla?retry_attempts=8&retry_delay=3&max_pool_size=50&max_idle_pool_size=10&checkout_timeout=0.1") # there is always same story with or without params. 
begin 

db.scalar("") 
... 
another_meth(params, db) 

channel = Channel(Nil).new(20) 
    groups.each do |group| 
     spawn one_more_meth(group, channel, db) 
    end 
    groups.size.times { channel.receive } 

ensure 
     db.close 
    end 
end 

def another_meth(p, db) 
deeper_meth(db) 
end 

def one_more_meth(group, channel, db) 
... 
db.query_all 
... 
channel.send(nil) 
end 
+0

應該是正確通過一個單一的DB整個程序周圍的:它處理池間應受。做任何查詢都可以工作,或者只在進行大量查詢時才發生錯誤?如果不是,它是否使用另一種語言,使用相同的連接URL? – RX14

+0

它發生了很多查詢。是的,在Crystal + 1應用程序中有10個獨立程序。但是我的pg – nobilik

+0

中有最多2000個連接,但在我的本地機器上,只有一個應用程序運行時出現同樣的錯誤。 – nobilik

回答

1

我遇到類似的問題,我發現的是,這樣做db.query時,你必須確保之一:

結果集保存到一個變量,使用後關閉它們

rs = db.query("") 
Class.from_rs(rs) 
rs.close 

或使用塊

db.query("") do |rs| 
    Class.from_rs(rs) 
end 
+0

這裏是新的修復,使rs.close不需要https://github.com/crystal-lang/crystal-db/commit/c63ea487486f0d1527d41b93b16a4eceed3516b7 – nobilik

+0

多數民衆贊成在偉大的,很好! – fridgerator