Tomoki Ota's Blog

article icon

【Go言語】SQLのコネクション

作成日 

sql.Open

sql.Openは必ずしもデータベースへのコネクションを確立するとは限りません。

func main() {
    _, err := sql.Open("mysql", "dummy:dummy@tcp(localhost:3306)/dummy")
    if err != nil {
        panic(err)
    }
    fmt.Println("Success!")
}

最初に sql.Open() を実行していますが、データベースを使用していなくてもこのコードは実行され、Success! と出力されます。

https://pkg.go.dev/database/sqlには以下のように書かれています。

Open may just validate its arguments without creating a connection to the database. To verify that the data source name is valid, call DB.Ping.

つまり、sql.Openは、データベースへのコネクションを確立せずに、引数を検証するだけする場合がある。DSNが有効かを確認するには、DB.Pingを呼び出す必要がある。

Ping

sql.Openの動作はSQLドライバーに依存しています。ドライバーによって、sql.Openはコネクションを確立せず、引数の妥当性だけを確認します。

db, err := sql.Open("mysql", "dummy:dummy@tcp(localhost:3306)/dummy")
if err != nil {
    return err
}
 
// Pingメソッドでコネクションを確立する
if err := db.Ping(); err != nil {
    return err
}

Ping()以外にもPingContext()が存在する。これはPingのキャンセルやタイムアウトのタイミングをContextに持たせることができる。

コネクションプール

Goでデータベースコネクションがどのように処理されるかを理解する必要がある。 sql.Openは*sql.DBを返し、これはデータベースへの1つのコネクションを表すのではなく、コネクションプールを表している。自分でプールを実装してはいけない。

プール内のコネクションは以下の2つの状態を保持する。

  • すでに使用中
  • アイドル

プールを作成したら、置き換えができる4つの設定パラメータがあり、*sql.DBの公開メソッドで設定できる。

メソッド説明デフォルト値
SetMaxOpenConnsデータベースへの最大オープンコネクション数無制限
SetMaxIdleConnsアイドル状態の最大コネクション数2
SetConnMaxIdleTimeコネクションが終了するまでのアイドル状態の最大時間無制限
SetConnMaxLifetimeコネクションをクローズする前にオープンしたままにできる最大時間無制限

本番レベルのアプリケーションでは、これらの4つのパラメータを設定する必要がある。 また、複数のコネクションプールを使うことも可能。

この記事をシェアするx icon
アイコン画像
Tomoki Ota

フルスタックエンジニア。Goが好き。趣味はカメラと旅行です📷