2009-07-17 3 views
34

나는 SqlConnection 개체를 인스턴스화하면 연결 풀에서 실제로 연결을 잡는 것을 이해합니다. Open()을 호출하면 연결이 열립니다. 해당 SqlConnection 개체에 대해 Close() 또는 Dispose() 메서드를 호출하면 연결 풀로 반환됩니다.연결 풀링을 사용하는 동안 SqlConnection을 실제로 닫으려면 어떻게해야합니까?

그러나 실제로 닫혀 있는지 또는 데이터베이스에 여전히 활성 연결이 있는지는 알 수 없습니다.

SqlConnection을 네트워크 수준에서 강제로 닫거나 적어도 닫을 때 알려주려면 어떻게해야합니까?

예 :

using(SqlConnection conn = new SqlConnection(DBConnString)) { 

    conn.Open(); 
    SqlCommand cmd = conn.CreateCommand(); 
    ... 
    cmd.ExecuteReader(CommandBehavior.CloseConnection); 
    ... 
} 
  • 먼저 실행 : 300 MS
  • 두 번째 실행 : 100 밀리
  • 세 번째 실행 : 오랜 시간 대기 후 100 밀리
  • 을 (30 분) : 300 ms

if 연결은 참으로 닫았고 두 번째 및 세 번째 실행은 300ms 여야합니다. 하지만 그 연결이 SQL Server의 활동 모니터를 확인한 실행에 대해 실제로 닫히지 않았 음을 알고 있습니다. 인증 등을 수행하기 위해 여분의 200ms가 필요하지 않습니다.

어떻게 연결을 강제로 닫으시겠습니까?

아이디어

  • 합니까 위해 CommandBehavior.CloseConnection 일? (분명히 아니?)
  • 연결 문자열에서 "Max Pool Size = 0"설정이 작동합니까? (이것은 pyrrhic 솔루션이 될 것입니다)
  • Dispose() 작동합니까?

참조 Connection Pooling

  • 답변

    48
    +2

    처음 응답자가 질문을 올바르게 읽으려면 +1. – Joe

    +1

    나는이 일을하고 있지만 내 SQL 연결은 여전히 ​​sp_who2에 나타나고 SQL 세션 보유 AppLocks는 잠긴 상태로 유지됩니다 (연결로 인해 죽을 것이라고 생각합니다). 나는 심지어 [''connStrBuilder.Polling = false'] (https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.close (v = vs.110) .aspx)를 설정합니다. –

    0

    CommandBehavior.CloseConnection에 대한 기사는 대개 때문에 바로이 사실을 권장하지 않습니다 - 당신은 연결이 폐쇄됩니다 확신 할 수 없다. (나는 이것에 대한 몇 가지 구체적인 증거를 찾으려고 노력할 것이다. 나는 이것을 희미한 기억으로부터 말하고있다.) 이 암시 적으로 Close()를 호출하기 때문에

    Dispose()확실한 방법입니다.

    @Alex에 의해 입증 된 using 구조는 암시 적으로 개체의 암시 적 처리가 추가 된 try-finally 구문을 작성하는 또 다른 (프로그래머가 익숙한) 방법입니다.

    편집 : 실제로 폐쇄 나에게 부당한 보인다 연결을 통해

    귀하의 우려 (편집 후 질문에). 연결은 모든 초기화를 거치지 않고도 쉽게 재사용 할 수 있도록 단순히 풀로 돌아갑니다. 그렇다고해서 Connection이 여전히 DB에 연결되어있는 것은 아닙니다.

    +2

    풀 **의 연결은 ** 여전히 DB에 활성 상태로 연결되어 있음을 의미합니다. 예를 들어, 당신은 Connection 객체를 닫을 수 있고, 접속이 여전히 풀에 있기 때문에 샤드 데이타베이스 잠금을 유지할 것입니다 (http : // stackoverflow.com/questions/520716/ado-net-sqlserver-how-to-prevent-closed-connection-holding-s-db-lock) –

    9

    연결 풀을 사용하지 않으려면 SqlConnection.ConnectionString 속성에 지정해야합니다. 예를 들어

    "Data Source=MSSQL1;Database=AdventureWorks;Integrated Security=true;Pooling=false;" 
    

    폐기 또는 SqlConnection 객체가 바로 연결을 종료하고 연결 풀에 반환하는 것입니다 닫는.

    3

    일반적으로 연결 풀이 작업을 수행하기를 원합니다. 연결을 정말로 닫지 않기를 원합니다.

    특히 연결을 풀로 반환하지 않으려면 어떻게합니까?

    +2

    풀의 연결은 잠금을 유지할 수 있습니다. –

    +1

    어떤 종류의 잠금을 사용하고 있는지 확실하지 않습니다. 기본 연결이 연결 풀로 반환 된 폐기 된 연결은 트랜잭션에 참여하거나 코드를 사용하는 것과 관련된 잠금을 보유해서는 안됩니다. 물론 네트워크 포트와 기타 리소스를 사용하고 있습니다.하지만 이러한 리소스를 구입하는 데 드는 비용은 왜 사용자가 * 무엇을 무료로하지 않는지 *입니다. 기본 데이터베이스 또는 이와 유사한 급격한 삭제/복원을 시도하지 않는 한 이러한 잠금은 문제가되지 않습니다. –

    +1

    풀에 연결하면 데이터베이스에 대한 독점적 액세스가 금지 될 수 있습니다. – kevmar

    23

    모에 Sisko의 대답 (전화 SqlConnection.ClearPool) 맞습니다.

    때때로 풀로 돌아 가기보다는 실제로 닫으려면 연결이 필요합니다. 예를 들어, 스크래치 데이터베이스를 생성하고, 스키마를 빌드하고, 테스트를 수행하고, 테스트가 모두 통과되면 스크래치 데이터베이스를 삭제하는 단위 테스트를 수행합니다.

    연결 풀링이 활성화되어 있으면 활성 연결이 여전히 남아 있기 때문에 데이터베이스 삭제 명령이 실패합니다. 프로그래머의 관점에서 볼 때 모든 SQLConnections는 닫혀 있지만 풀은 여전히 ​​열린 상태이므로 SQL Server는 드롭을 허용하지 않습니다.

    연결 풀링 처리 방법에 대한 최상의 설명서는 MSDN에서 this page on SQL Server Connection Pooling입니다. 하나는 연결 풀링을 완전히 해제하고 싶지 않습니다. 반복되는 열기 및 닫기로 성능이 향상되기 때문입니다.하지만 때때로 SQLConnection에서 "강제 종료"를 호출하여 데이터베이스를 놓을 수 있어야합니다.

    이것은 ClearPool에서 수행됩니다. 닫히거나 처분하기 전에 SqlConnection.ClearPool(connection)으로 전화하면 닫고 처리하면 실제로 사라집니다.

    +0

    당신이 설명하는 유스 케이스는 거의 정확히 내가 해왔 던 것입니다 - 특정 db 액세스 패턴의 성능을 테스트하고, 콜드 프로 시저/데이터 캐시와 물론 연결을 사용합니다. –

    +0

    제공하신 링크가 질문 텍스트에 추가되었습니다. 감사. –

    +0

    나 같은 시나리오 :-) –

    -2

    Robert의 대답은 SqlConnection.ClearPool(TheSqlConn)입니다. 풀이 필요할 때 상호 작용할 수 있다는 것을 알면 좋습니다.

    사례 : 우리는 연결을 망쳐 다시 풀에 들어가게했습니다. 우리는 그것이 망가 졌음을 감지하고 새로 고침하여 다음 사용자에게 문제가 발생하지 않도록합니다.

    해결 방법은 다음과 같습니다. 연결이 망가 졌음을 감지하고 풀에서 완전히 제거하여 풀이 새로운 연결로 채워지도록합니다.

    SqlClient.SqlConnection을 작성한 지 10 년이되었고 지금까지도 풀과 상호 작용할 생각조차 들지 않았습니다.

    관련 문제