2013-11-14 6 views
8

sql.Openを(再利用)がsql.DBゴー/ Golang sql.DBは機能に

*型の変数を返します。私は、すべてのデータベースが

を呼び出すようにする必要があり10個の他の関数を呼び出す関数を持っていますそれは、効率的な/より補正することである:

  • すべての機能に* sql.DBポインタを送ったり、
  • は、それぞれの機能に新しい* sql.DBオブジェクトを作成します
私は現在、各関数へのポインタを送信していますし、私のドライバーが壊れているようですので、私は聞いてるのよ、なぜ

func DoLotsOfThings() { 
    db, _ := sql.Open() 
    defer db.Close() 
    DoTask1(db) 
    DoTask2(db) 
} 

または

func DoLotsOfThings() { 
    DoTask1() 
    DoTask2() 
} 

func DoTask1() { 
    db, _ := sql.Open() 
    defer db.Close() 
} 

func DoTask1() { 
    db, _ := sql.Open() 
    defer db.Close() 
} 

を意味

理由があります。私はhttp://code.google.com/p/odbcを使用しています。これは、それぞれの機能が独自のものでなければならないと信じており、ドライバの内部構造に頼ることができます。

EDIT

REドライバの破損、それだけで高トラフィック環境で起こります。そして、それは、例えば、10分ほどの時間が経過した後にのみ起こります。これは、ドライバを使用して動作を停止させる何らかのメモリリークがあると私に信じさせる。しかし、* sql.DBのすべてのインスタンスに対してdb.Close()を延期するので、この問題を解決するために他に何ができるか分かりません。

andybalholmはそれだけで私は起動していないとき、何かを実行しようとした後、壊れているため、接続プーリングは、正確であると思われ、内部的に処理されると言うsql.Open()

私は囲碁のアプリを実行したままにした場合どんな種類のSQLクエリも実行することはできませんが、別のGoテストを別々に実行してMSSQLに接続してクエリを実行しようとすると、動作します。

+0

再現可能なサンプルをhttps://code.google.com/p/odbc/issues/listに投稿できる場合は、修正を試みます。 – alex

答えて

6

データベース接続をその場所全体で開く必要はありません。データベース/ sqlパッケージでは、内部で接続プーリングが行われ、必要に応じて接続の開閉が行われますが、同時に使用できる単一接続のように見えます。

おそらく、ドライバ破損の原因を別の場所で調べる必要があります。それについての詳細は、人々が何が起こっているのか把握しやすくなります。

+0

したがって、sql.Openと結果として得られる* sql.DBへの参照が1つ必要です。プーリングについては正しいと思われますが、クエリを実行しようとするとエラーが発生します。奇妙なことに、私のgoアプリケーションはMSSQLに接続できなくなりますが、その外では、ストアドプロシージャを実行していない限り、接続できるテストを実行できます。それはすべて非常に奇妙です。 –

+0

データベース/ SQLアプリケーションをデバッグしようとするときに覚えておくべきことの1つは、接続プーリングのためにsql.Openを実行したときに接続エラーが表示されないことです。彼らはあなたが接続で最初のクエリを実行するまで待つ。 – andybalholm

18

var db *sql.DBをグローバルに宣言し、コード全体で再利用してください。

var db *sql.DB 

func DoLotsOfThings() { 
    DoTask1(db) 
    DoTask2(db) 
} 

func main() { 
    db, _ = sql.Open() # or whatever you use 
    defer db.Close() 
    DoLotsOfThings() 
} 

がグローバルにもいくつかの追加の利点などSetMaxIdleConns(規制接続プールのサイズ)や、アプリケーション全体でpreparing SQL文を持って*sql.DBの宣言:ここでは例(簡体字)です。

+0

そのメモをありがとう! – Anatoly