質問

特定のデータベースを削除して再作成した後、SQL Serverが接続を削除する際に問題が発生し、次に同じデータベースで新しい接続に対してコマンドを実行しようとすると、次のようになります:

  

リクエストをサーバーに送信するときにトランスポートレベルのエラーが発生しました。 (プロバイダー:共有メモリプロバイダー、エラー:0-パイプの反対側にプロセスはありません。)

これはTCPバージョンです(別のサーバーに接続しようとした場合)

  

リクエストをサーバーに送信するときにトランスポートレベルのエラーが発生しました。 (プロバイダー:TCPプロバイダー、エラー:0-既存の接続がリモートホストによって強制的に閉じられました。)

問題を再現する手順は次のとおりです。

  1. データベースへの接続を開き、sqlコマンドを実行します
  2. データベースをドロップ
  3. データベースを再作成
  4. 同じデータベースへの新しい接続を開き、それに対してコマンドを実行しようとします

結果:例外が表示されます

コードは次のとおりです:

using (var conn = new System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=DBNAME;Integrated Security=True"))
{
    conn.Open();
    var cmd = conn.CreateCommand();
    cmd.CommandText = "UPDATE ...";
    cmd.ExecuteNonQuery();
}

string sql = "Alter Database DBNAME set single_user with rollback immediate drop database DBNAME";
var server = new Microsoft.SqlServer.Management.Smo.Server(".");
server.ConnectionContext.ExecuteNonQuery(sql);
server.ConnectionContext.Disconnect();

sql = File.ReadAllText("PathToDotSqlFile..."));
server = new Microsoft.SqlServer.Management.Smo.Server(".");
server.ConnectionContext.ExecuteNonQuery(sql);
server.ConnectionContext.Disconnect();

using (var conn = new System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=WER_CONFIG;Integrated Security=True"))
{
    conn.Open();
    var cmd = conn.CreateCommand();
    cmd.CommandText = "UPDATE ...";
    cmd.ExecuteNonQuery();
}

エラーは、最後の「cmd.ExecuteNonQuery()」行で発生します。接続するたびに新しい接続を作成しているにもかかわらず、SQLサーバーは何か(またはおそらくADO.netコード)を追跡しているので、次に接続を要求すると、すでに使用されているものが提供されますまたはサーバー側で閉じられています。別のコマンドを実行しようとするまで、サーバーによって閉じられたことを認識しません(おそらく、接続されているデータベースが削除されたためです)。

最初のクエリを実行する最初のステップを実行せず、データベースを削除して再作成し、コマンドを実行するだけの場合、このエラーは表示されないことに注意してください。データベースが削除される前に初期接続を確立することは、このエラーの重要な部分だと思います。

また、外部プロセスを使用してデータベースを削除および再作成しようとしました:

ProcessStartInfo info = new ProcessStartInfo("sqlcmd.exe", " -e -E -S . -Q \"Alter Database DBNAME set single_user with rollback immediate drop database DBNAME\"");
var p = Process.Start(info);
p.WaitForExit();

info = new ProcessStartInfo("sqlcmd.exe", " -i " + PathToDotSqlFile);
p = Process.Start(info);
p.WaitForExit();

そしてそれは助けにはなりませんでした。

新しいSqlConnectionを作成し、プールからではなくクリーンであることを確認する方法はありますか?この問題を解決する方法に関する他の提案はありますか?

更新:SqlConnection.ClearPool()を使用することで問題は解決しましたが、pooling = falseで接続文字列を編集することを選択しましたが、これも機能しました。

役に立ちましたか?

解決

ADO.NETは接続プールを自動的に管理します。 「閉じる」ときアプリケーション内の接続は、同じ接続文字列を使用して接続を要求した場合にプールに返され、維持されます。これが、「新規」の理由です。接続が古い。

パラメーターとして pooling = false を接続文字列に追加することにより、この動作をオフにしようとすることができます。

他のヒント

SQL2008については知りませんが、これはアプリケーション側の接続プーリングの問題のように聞こえます。昔、「OLEDB Services = -1」を追加しました;接続文字列に接続プールをオフにします。これを行うには、おそらくもっとエレガントな方法があるでしょう。

edit:ADO.Net 2.0はClearConnectionをSQLConnectionオブジェクトに追加したようです。 ( http:// msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.clearpool(VS.80).aspx )これが機能するかどうかを知りたいと思います。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top