概要
GoのSQL用ライブラリsqlcで、PostgreSQLに接続する際はpgxというライブラリが公式では使用を案内しています。ただ、sqlcのドキュメントGetting started with PostgreSQLに沿って実装すると、SQLを連続で投げた発行した場合にconn busy
というエラーが発生します。
接続周りのエラーということはメッセージから推測できますが、ではどうやって対応するかということをメモ書きします。
前提
- 使用したpgxのバージョンは
v5.7.5
です。
対応案
対応方法はいくつかあると思いますが、stackoverflowの"conn busy" error when executing update against result from queryの回答で紹介されているconnection poolを使う対応が良いかなとは思いました。connection poolを使う実装は、sqlc と pgxpool でトランザクションが参考になります。
実装サンプル
コネクションプールを作成して、クエリのオブジェクトを取得するサンプル実装は以下になります。
// DBの接続文字列から設定を取得
config, err := pgxpool.ParseConfig(os.Getenv("DB_CONNECT"))
if err != nil {
panic(err)
}
// 接続プール設定
maxConn, err := strconv.Atoi(os.Getenv("DB_MAX_CONNS"))
if err != nil {
panic(err)
}
minConn, err := strconv.Atoi(os.Getenv("DB_MIN_CONNS"))
if err != nil {
panic(err)
}
config.MaxConns = int32(maxConn) // 最大接続数
config.MinConns = int32(minConn) // 最小接続数
config.MaxConnLifetime = time.Hour * 2
config.MaxConnIdleTime = time.Minute * 30
// プールの生成
pool, err := pgxpool.New(context.Background(), config.ConnString())
if err != nil {
return nil, err
}
// クエリのオブジェクト取得。クエリの取得後は通常のConnectと同様の実装になる。
queries := db.New(pool)
defer pool.Close()