2009-04-23 3 views
6

나는 LINQ를 사용할 때 SQL 연결 누수를 얻지 못했지만 NumberOfReclaimedConnections의 perfmon 추적은 높은 숫자를 표시하고로드가 높을 때 "제한 시간 만료되었습니다."와 같은 예외가 발생하는 경우가 있습니다. 모든 풀링 된 연결이 사용 중이며 최대 풀 크기에 도달했기 때문에 발생했을 수 있습니다. "LINQ를 사용하여 SQL 연결 누수를 가져올 수 있습니까?

우리는 데이터로드에 Dispose를 사용하지 않으므로 사용하지 마십시오. 몇몇 기사와 blogpost는 이것이 문제가되어서는 안된다고 말합니다.

때때로 이러한 예외가 발생합니다. 그러나 우리가하는 모든 linq 쿼리가 연결을 열어 둘 수는 없다. 그렇다면 우리는 훨씬 더 많은 예외를 가질 것이다.

편집 됨

응용 프로그램은 WCF 서비스입니다.

Linq와 대부분의 기사의 문서를 보면 Dispose가 연결을 해제 할 필요가 없다고 주장합니다. 그들은 DataCOntext가 필요한 짧은 시간 동안 만 연결을 유지한다고 주장합니다.

답변

8

DataContext이 처리되지 않고 계속 살아있을 경우 연결된 연결도 계속 유지됩니다. 데이터베이스 연결은 관리되지 않는 리소스이며 관리되지 않는 모든 리소스는 올바르게 처리해야합니다.

지연로드를 사용하고 잘 정의 된 범위가없는 경우에도 논리 작업 단위 (logical unit)의 끝에서 데이터베이스 연결을 정리해야합니다. ASP.NET 응용 프로그램에서는 요청 처리가 끝날 때 Globals.asax 파일의 Application_EndRequest 메서드에서 최신 상태가 될 수 있습니다. WCF 서비스에서 모든 활성 데이터 컨텍스트는 모든 서비스 메서드 호출 끝에 처리해야합니다.

이 문서는 모호하며 대부분의 경우 DataContext를 폐기하지 않고도 벗어날 수 있지만 연결에서로드 된 데이터가 연결 자체를 유지하는 시나리오가있는 것으로 보입니다. 이 문제가 귀하의 경우에 일어나는지 확인하는 가장 쉬운 방법은 테스트하는 것입니다.

+0

좋은 추가. 감사합니다 :) –

0

데이터베이스에 교착 상태가 있습니까? 액티비티 모니터를 간략히 살펴보면 몇 가지 정보를 얻을 수 있습니다.

DataContext 수명주기를 관리하려면 어떻게해야합니까? 어떤 종류의 응용 프로그램 (웹 사이트, Windows 클라이언트, 기타)을 작성 했습니까?

쿼리 또는 작업에서 DataContext를 사용하면로드 된 엔터티가 느린로드 & 등이 될 수 있으므로 연결을 유지하므로 응용 프로그램에서 DataContext를 사용하는 방법을 계획해야합니다.

WCF services ..이 경우, 나는 "요청 당 하나의 맥락"접근 방식의 큰 팬이다. 완료 될 때 컨텍스트가 삭제되도록 using() 문 내에서 데이터 작업을 래핑하는 것이 좋습니다.

+0

우리는 교착 상태에 아무런 문제가 없습니다. 적어도 제가 지금 알고있는 것은 아닙니다. 우리는 그것을 모니터링하고 있습니다. 응용 프로그램은 WCF 서비스이며 datacontext는 서비스 호출보다 오래 살아서는 안됩니다. – Atle

4

내가 발견 좀 더이

내가 그것을 재현이 작은 테스트 코드를 만들어 .. LINQ가 열려있는 연결을 떠날 바보짓을 할 수 있다고 말한다 어디이 question and answer을 발견 검색 한 후. 열거자를 foreach로 바꾼다면 제대로 작동하지만 Enumerator는 연결을 유지합니다.

public Organisation RunTestQuery2() 
{ 
    IEnumerable<Organisation> orgs = base.GetEntities<Organisation>().Take(5); 

    var enumerator = orgs.GetEnumerator(); 
    int i = 0; 


    while (enumerator.MoveNext()) 
    { 
     var org = enumerator.Current; 
     Debug.WriteLine(org.DescribingName); 
     if (i == 3) 
     { 
      return org; 
     } 
     i++; 
    } 

    return null; 
} 

컨텍스트에서 처분 할 호출을 추가하면 사라집니다.

+0

그건 그냥 컴파일러의 마법. foreach는 열거자를 인스턴스화하고 false를 반환 할 때까지 MoveNext를 호출 한 다음 열거 자에서 Dispose를 호출하는 구문 캔디입니다. 그냥 참고하시기 바랍니다. – Kilanash

관련 문제