6

JavaとC#では、どちらもSystem.terminate()のようなものを持っています。プログラムに開いているデータベース接続、データベースリーダー、およびデータベースコマンド変数があり、catch句でプログラムを終了した場合、データベースリソースは引き続き使用されますか?または、プログラム全体が終了したばかりなので、自動的に解放されますか?

通常、通常のプログラムの終了または予期しないプログラムの終了にかかわらず、データベース接続を常に解放するために、このようなケースをどのように処理する必要がありますか?良い習慣はありますか?

4

8 に答える 8

6

プロセスが終了すると、関連するすべてのリソース(メモリ、ハンドル、接続など)が解放されます。

通常、C#では、Disposeパターン/usingステートメントを使用して不足しているリソースを制御します。

于 2009-06-06T21:30:23.730 に答える
5

特に接続を閉じない限り、タイムアウトになるまで接続は開いたままになります。

私はこれをC#で数回難しい方法で見つけました。ベストプラクティスでは、不要になることがわかっているリソースをシャットダウン/クローズする必要があります。ファイルI/Oストリーム、DB接続など

于 2009-06-06T21:29:49.707 に答える
1

C#では、ガベージコレクションされるオブジェクトにファイナライザーが実装されている場合、暗黙的なクリーンアップはガベージコレクターによって実行されます。データベース接続などの管理されていないリソースのクリーンアップは、Disposeメソッドで実行できます。

詳細については、次の記事を参照してください。

管理されていないリソースをクリーンアップするためのファイナライズと破棄の実装
http://msdn.microsoft.com/en-us/library/b1yfkh5e(VS.71).aspx

于 2009-06-06T21:36:34.343 に答える
1

SQL Serverを使用している場合は、sysprocessesを確認するか、sp_who2を実行できます。私は自分のマシンでこれをテストしましたが、接続は閉じられます。

Console.Write("Opening connection");
Console.ReadLine();
SqlConnection connection = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=SeniorMail;Integrated Security=SSPI;");
connection.Open();
SqlCommand command = new SqlCommand("SELECT count(*) from Account", connection);
Console.Write("Running sql");
Console.ReadLine();
int? count = command.ExecuteScalar() as int?;
Console.Write("Now I'll throw an exception");
Console.ReadLine();
int a = 0, b = 1, c = 0;

try
{
    c = b / a;
}
catch
{
    Environment.Exit(1);
}

「例外をスローします」のいずれかの側のsp_who2を確認しましたが、アプリの終了後に接続が失われたことがわかります。

于 2009-06-06T22:12:50.120 に答える
1

プロセスが終了すると、プロセスが開いているすべてのファイル記述子がオペレーティング システムによって解放される必要があります。ファイル記述子にはファイルとソケットが含まれており、通常はデータベース接続をカバーします。

つまり、クライアントが終了すると接続が閉じられるということだけです。サーバーが何をするかはわかりません。記述方法によっては、サーバーが接続を開いたままにして、クライアントからのメッセージが届かないことを期待したり、データを送信しようとしたりする可能性さえあります。これらは最終的にタイムアウトになる可能性がありますが、これは十分に計画されていない可能性があります。(適切な RDBMS の場合はそうである必要がありますが、そうでない場合もあります。) したがって、RDBMS によっては、サーバーにリソースを解放するように指示するために、サーバーがダウンしていることを伝えるためにいくつかの手順を実行する必要がある場合があります。

于 2009-06-06T22:07:15.793 に答える
0

一般的なPOSIXの動作では、プログラムが終了すると、すべてのファイルハンドル、ネットワーク接続などが閉じられます。その時点でもう一方の端が正しいことをするかどうかは未解決の問題ですが、かなり人気のあるRDBMSを使用している場合は、問題ありません。

于 2009-06-06T21:32:21.573 に答える
0

C# では、通常、接続を使用した直後に接続を閉じます。たとえば、次のようになります。

using(SqlConnection connection = ...)
{
   ... do something ...
} // connection disposed / closed here

ただし、通常は接続プールを使用し、接続をプールに返すだけです。そのため、プロセスはデータベース サーバーへのアクティブな接続を維持します。

正常にシャットダウンすると、接続プールは間違いなくクリーンアップされ、データベースへの実際の接続は閉じられます (これは、データベース サーバーで開いている接続を調べることで確認できます)。

ただし、接続を閉じずにアプリケーションがクラッシュする場合 (Environment.FailFast の呼び出しなど) があります。この場合、接続は最終的にタイムアウトになり、データベース サーバーによって閉じられます。

于 2009-06-06T21:45:27.290 に答える
-1

次のGCでクリアする必要がありますが、正確には、C#では、構造化例外処理のfinallyブロックで接続を閉じることができます。

try {
  // open DB connection
} catch (Exception ex) {
  // deal with exception
} finally {
  // close and dispose connection
}
于 2009-06-06T21:30:32.623 に答える