私のコードは、クエリを作成するたびに DB を開き、QueryRow() を実行し、結果を変数にスキャンしてから、defer を使用して DB と行を閉じるように設定されています。ただし、接続リークが発生していますが、すべてを閉じていると思います。
close ステートメントを defer から取り出して、使い終わったときに閉じようとしました。Goで行挿入のために単一のPostgres DB接続を再利用する方法に従ってください? しかし、私は答えに従っていると信じていますが、それでも運はありません。
func (a AccessPostgres) OpenDB() (*sql.DB, error) {
dbinfo := fmt.Sprintf("user=%s password=%s dbname=%s sslmode=disable",
user, password, a.DBName)
var err error
db, err := sql.Open("postgres", dbinfo)
if err != nil {
return nil, err
}
return db, nil
}
func (a AccessPostgres) Run(s string) error {
db, err := a.OpenDB()
if err != nil {
return err
}
defer db.Close()
_, err = db.Exec(s)
if err != nil {
return err
}
return nil
}
type Row struct {
Collection_time string
Dbid string
Hostname string
Dbname string
Name string
Value string
}
type QueryResult struct {
Rows []Row
}
func (a AccessPostgres) Query(q string) ([]byte, error) {
db, err := a.OpenDB()
if err != nil {
return nil, err
}
defer db.Close()
rows, err := db.Query(q)
if err != nil {
return nil, err
}
defer rows.Close()
var qr QueryResult
for rows.Next() {
var r Row
err := rows.Scan(&r.Collection_time, &r.Dbid, &r.Hostname, &r.Dbname, &r.Name, &r.Value)
if err != nil {
return nil, err
}
qr.Rows = append(qr.Rows, r)
}
result, err := json.Marshal(qr)
if err != nil {
return nil, err
}
return result, nil
}
ほとんどの場合、うまく機能します。しかし、このコードは一定間隔で実行され、しばらくすると「pq: 申し訳ありませんが、クライアントが多すぎます」というエラーが表示されます。それだけです。