Transaction Binding = Explicit Unbindを使用する場合、接続は閉じません。接続文字列内
-
10-07-2019 - |
質問
推奨されるように、接続文字列で Transaction Binding = Explicit Unbind
を使用しますこちら。I´ mもタイムアウト付きのTransactionScopeを使用しているためです。問題は、接続が破棄された後に閉じられていないようであり、最終的に接続プールで使用可能な接続がなくなることです。 TransactionTimeoutIssueDemo(リンクを参照)を変更し、ループ内でTransactionScopeTest()(明示的なアンバインド接続文字列を使用)を実行して、接続プール内の使用可能なすべての接続を使い切るのと同じ結果になりました。プール内の接続のデフォルト値は100ですが、これは、たとえば Max Pool Size = 10
の設定を使用して変更できます。明示的にアンバインドを使用すると、SqlConnectionとTransactionScopeの両方が using
句で使用されている場合でも、接続は解放されないようです。誰でもこれを処理する方法を知っていますか?
解決
接続は、例のように例外が発生した場合にのみプールに留まり、再利用されないようです。タイムアウトを増やすと、接続が再利用されます。
この問題の回避策は、次のような例外が発生した場合に接続プールをクリアすることです。
using (SqlConnection con = new SqlConnection(connectionString))
{
con.Open();
try
{
Console.WriteLine("Server is {0}", con.ServerVersion);
Console.WriteLine("Clr is {0}", Environment.Version);
for (int i = 0; i < 5; i++)
{
using (SqlCommand cmd = con.CreateCommand())
{
cmd.CommandText = "insert into TXTEST values ( " + i + " )";
cmd.ExecuteNonQuery();
}
Console.WriteLine("Row inserted");
}
Thread.Sleep(TimeSpan.FromSeconds(1));
}
catch
{
SqlConnection.ClearPool(con);
throw;
}
}
ほとんどの場合、トランザクションはタイムアウト内に完了し、すべて正常に完了します。トランザクションが実際にタイムアウトすると、再利用されないダーティ接続をクリーンアップするためにプールをクリアします。これはもちろん、この問題の影響を受けないプール内の他の接続に影響します。
これはい回避策ですが、動作するようです。
他のヒント
価値のあることについては、この問題は.Net 4.0で修正されました。