문제

주어진 데이터베이스를 삭제하고 재창조 한 후 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 Server는 다음에 연결을 요청할 때 이미 사용 된 것 (또는 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 ()을 사용하면 문제가 해결되었지만 풀링 = false로 연결 문자열을 편집하기로 결정했습니다.

도움이 되었습니까?

해결책

ado.net은 연결 풀을 자동으로 관리합니다. 응용 프로그램에서 "연결"을 "닫으면"동일한 연결 문자열과 연결을 요청할 경우 수영장으로 돌아와 살아있는 상태로 유지됩니다. 이것이 당신의 "새로운"연결이 부실한 이유 일 수 있습니다.

추가 하여이 동작을 끄려고 노력할 수 있습니다. pooling=false 연결 문자열의 매개 변수로

다른 팁

SQL2008에 대해 알지 못하지만 응용 프로그램 측면에서 연결 풀링 문제처럼 들립니다. 예전에는 연결 문자열에 "OLEDB SERVICES = -1"을 연결하여 연결 풀링을 끄기 위해 추가했습니다. 지금이 작업을 수행하는 더 우아한 방법이있을 것입니다.

편집 : ado.net 2.0은 SQLConnection 객체에 ClearPool 함수를 추가 한 것으로 보입니다. (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.clearpool(vs.80).aspx) 이것이 효과가 있는지 알고 싶습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top