我有一个奇怪的用例,说明我们如何在一段代码中处理SQL连接。为了测试这个,我创建了一个单元测试:
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();
}
基本上在第一次连接抛出后因为DB不存在,最后一个抛出也是,显然是因为DB处于&#34;破坏&#34;状态?
如果我删除第一个using
块,一切正常,如果我调试并缓慢地逐步执行代码(在最后一次查询之前等待几秒钟),一切正常。
有关可能导致此行为的任何想法吗?
答案 0 :(得分:1)
所以MultipleActiveResultSets没有帮助但是如果你设置了我找到了两个解决方案:
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();
}
显然,这并没有真正解释为什么崩溃的连接在游泳池中并且重复使用...