接続の管理

ほとんどのプログラムでは、sql.DB接続プールのデフォルトを調整する必要はありません。しかし、一部の高度なプログラムでは、接続プールのパラメーターを調整したり、接続を明示的に操作したりする必要があるかもしれません。このトピックでは、その方法について説明します。

sql.DBデータベースハンドルは、複数のゴルーチンによる同時使用に対して安全です(つまり、このハンドルは他の言語で「スレッドセーフ」と呼ばれるものです)。他のデータベースアクセスライブラリの中には、一度に1つの操作にしか使用できない接続に基づいたものがあります。このギャップを埋めるために、各sql.DBは、基盤となるデータベースへのアクティブな接続のプールを管理し、Goプログラムの並列処理に必要な新しい接続を作成します。

接続プールは、ほとんどのデータアクセスニーズに適しています。sql.DBQueryまたはExecメソッドを呼び出すと、sql.DBの実装はプールから利用可能な接続を取得するか、必要に応じて新しい接続を作成します。パッケージは、不要になった接続をプールに戻します。これにより、データベースアクセスで高度な並列処理がサポートされます。

接続プールプロパティの設定

sqlパッケージが接続プールを管理する方法を指示するプロパティを設定できます。これらのプロパティの効果に関する統計情報を取得するには、DB.Statsを使用します。

オープン接続の最大数の設定

DB.SetMaxOpenConnsは、オープン接続の数に制限を設けます。この制限を超えると、新しいデータベース操作は、既存の操作が完了するまで待機し、その時点でsql.DBは別の接続を作成します。デフォルトでは、接続が必要なときに、既存のすべての接続が使用中の場合、sql.DBは新しい接続を作成します。

制限を設定すると、データベースの使用がロックまたはセマフォの取得に似たものになり、アプリケーションが新しいデータベース接続を待ってデッドロックする可能性があることに注意してください。

アイドル接続の最大数の設定

DB.SetMaxIdleConnsは、sql.DBが維持するアイドル接続の最大数の制限を変更します。

特定のデータベース接続でのSQL操作が終了した場合、通常、すぐにシャットダウンされることはありません。アプリケーションはすぐにそれを再び必要とする可能性があり、オープン接続を維持することで、次の操作のためにデータベースに再接続する必要がなくなります。デフォルトでは、sql.DBは常に2つのアイドル接続を維持します。制限を引き上げることで、並列処理が多いプログラムでの頻繁な再接続を回避できます。

接続がアイドル状態になることができる最大時間の設定

DB.SetConnMaxIdleTimeは、接続が閉じられるまでにアイドル状態になることができる最大時間を設定します。これにより、sql.DBは指定された時間よりも長くアイドル状態になっている接続を閉じます。

デフォルトでは、アイドル接続が接続プールに追加されると、再び必要になるまでそこに残ります。DB.SetMaxIdleConnsを使用して、並列アクティビティのバースト中に許可されるアイドル接続の数を増やす場合、DB.SetConnMaxIdleTimeも使用すると、システムが静かなときに後でこれらの接続を解放するように手配できます。

接続の最大有効期間の設定

DB.SetConnMaxLifetimeを使用すると、接続を開いたままにできる最大時間を設定できます。

デフォルトでは、接続は、上記の制限に従って、任意の時間使用および再利用できます。ロードバランシングされたデータベースサーバーを使用するシステムなど、一部のシステムでは、アプリケーションが再接続せずに特定の接続を長時間使用しないようにすることが役立つ場合があります。

専用接続の使用

database/sqlパッケージには、データベースが特定の接続で実行された一連の操作に暗黙的な意味を割り当てる可能性がある場合に使用できる関数が含まれています。

最も一般的な例はトランザクションです。トランザクションは通常、BEGINコマンドで開始し、COMMITまたはROLLBACKコマンドで終了し、それらのコマンド間の接続で発行されたすべてのコマンドが全体的なトランザクションに含まれます。このユースケースでは、sqlパッケージのトランザクションサポートを使用します。「トランザクションの実行」を参照してください。

一連の個々の操作をすべて同じ接続で実行する必要があるその他のユースケースでは、sqlパッケージは専用接続を提供します。DB.Connは、専用接続、sql.Connを取得します。sql.Connには、BeginTxExecContextPingContextPrepareContextQueryContextQueryRowContextメソッドがあり、これらはDBの同等のメソッドのように動作しますが、専用接続のみを使用します。専用接続が終了したら、コードでConn.Closeを使用して解放する必要があります。