2017-02-27 8 views
1

コードでSQL接続を処理する方法が変わっています。これをテストするために、私はユニットテストを作成しました:DBが存在しないため、最初の接続がスロー基本的に後にDBは、「壊れた」状態になって明らかにのでSQL Server接続エラーにより後続の接続がブロックされる

var masterBuilder = new SqlConnectionStringBuilder("Server=CHILTERN8564;Integrated Security=SSPI"); 
var databaseBuilder = new SqlConnectionStringBuilder(masterBuilder.ConnectionString); 
databaseBuilder.InitialCatalog = "CoreIssue"; 

using (var conDatabase = new SqlConnection(databaseBuilder.ConnectionString)) 
{ 
    Assert.Throws<SqlException>(conDatabase.Open); // crash as DB does not exist 
} 

using (var conMaster = new SqlConnection(masterBuilder.ConnectionString)) 
{ 
    // let's create the DB 
    conMaster.Open(); 
    new SqlCommand("CREATE DATABASE CoreIssue", conMaster).ExecuteNonQuery(); 
} 

using (var conDatabase = new SqlConnection(databaseBuilder.ConnectionString)) 
{ 
    // CRASH! even if the DB exists. 
    conDatabase.Open(); 
    new SqlCommand("CREATE TABLE Bob(name varchar(10))", conDatabase).ExecuteNonQuery(); 
} 

、最後のものは、同様にスロー?

最初のusingブロックを削除した場合、コードをゆっくりとデバッグしてから(最後のクエリの数秒前に待つ)すべてが機能します。

この現象の原因は何ですか?

databaseBuilder.Pooling = false; 

または

SqlConnection.ClearAllPools(); 

を呼び出すをので、テストは次のようになります:

明らか
[Test] 
public void Test() 
{ 
    var masterBuilder = new SqlConnectionStringBuilder(@"Server=localhost\sqlexpress;Integrated Security=SSPI"); 
    var databaseBuilder = new SqlConnectionStringBuilder(masterBuilder.ConnectionString); 
    databaseBuilder.InitialCatalog = "CoreIssue"; 
    //databaseBuilder.Pooling = false; <- fixes problem 

    using (var conDatabase = new SqlConnection(databaseBuilder.ConnectionString)) 
    { 
     Assert.Throws<SqlException>(conDatabase.Open); // crash as DB does not exist 
    } 

    SqlConnection.ClearAllPools(); //<- also fixes problem 

    using (var conMaster = new SqlConnection(masterBuilder.ConnectionString)) 
    { 
     // let's create the DB 
     conMaster.Open(); 
     new SqlCommand("CREATE DATABASE CoreIssue", conMaster).ExecuteNonQuery(); 
    } 

    using (var conDatabase = new SqlConnection(databaseBuilder.ConnectionString)) 
    { 
     // CRASH! even if the DB exists. 
     conDatabase.Open(); 
     new SqlCommand("CREATE TABLE Bob(name varchar(10))", conDatabase).ExecuteNonQuery(); 
    } 

あなたが設定している場合、

+0

MultipleActiveResultSets = trueを入力するとどうなりますか。あなたの接続文字列に?ちょっと興味があるんだけど。 – manderson

+0

瞬時にデータベースを作成する。私はここで何が起こっていると思うのは、データベースが存在しないので、最初のUSINGが死ぬのですが、2番目のSQL Serverはまだデータとログファイルを作成しているので、3番目のクエリ実行します。これは、あなたがコードをゆっくり歩いていくとすべてが機能する理由になります。 –

+0

私はそれについて考えましたが、最初の '使用する 'がなければ、すべてが機能します...問題を引き起こしていると思われる最初のものを使用しています... – Tallmaris

答えて

1

のでMultipleActiveResultSetsは役立ちませんが、私は2つの解決策を見つけましたこれは、実際にクラッシュした接続がプール内にあって再利用された理由を説明していません。