[C#] “열기 / 닫기”SqlConnection 또는 계속 열려 있습니까?

정적 메서드를 사용하여 간단한 정적 클래스에서 비즈니스 로직을 구현했습니다. 이러한 각 메소드는 호출시 SQL 연결을 열거 나 닫습니다.

public static void DoSomething(string something)
{
    using (SqlConnection connection = new SqlConnection("..."))
    {
        connection.Open();

        // ...

        connection.Close();
    }
}

하지만 연결을 열고 닫지 않으면 성능이 절약 된다고 생각 합니다 . OleDbConnection 클래스 (SqlConnection에 대해 확실하지 않음)로 오래 전에 몇 가지 테스트를 수행 했으며 다음과 같이 작동하는 데 확실히 도움이되었습니다 (내가 기억하는 한).

//pass the connection object into the method
public static void DoSomething(string something, SqlConnection connection)
{
    bool openConn = (connection.State == ConnectionState.Open);
    if (!openConn)
    {
        connection.Open();
    }

    // ....

    if (openConn)
    {
        connection.Close();
    }
}

그래서 질문은-방법 (a) 또는 방법 (b)를 선택해야합니까? 연결 풀링이 저에게 성능을 저장했다는 또 다른 스택 오버플로 질문을 읽었습니다. 전혀 신경 쓸 필요가 없습니다.

추신. ASP.NET 앱입니다. 연결은 웹 요청 중에 만 존재합니다. 윈-앱이나 서비스가 아닙니다.



답변

옵션 a를 고수하십시오 .

연결 풀링은 당신의 친구입니다.


답변

매번 방법 (a)를 사용하십시오. 응용 프로그램 확장을 시작할 때 상태를 처리하는 논리는 그렇지 않으면 정말 고통 스러울 것입니다.

연결 풀링은 주석에 표시된대로 수행합니다. 애플리케이션이 확장 될 때 어떤 일이 발생하는지, 연결 열기 / 닫기 상태를 수동으로 관리하는 것이 얼마나 어려울 지 생각해보십시오. 연결 풀은이를 자동으로 처리하는 훌륭한 작업을 수행합니다. 성능이 걱정된다면 어떤 것도 차단되지 않도록 일종의 메모리 캐시 메커니즘을 생각해보십시오.


답변

연결이 끝나면 항상 연결을 닫으십시오. 그러면 기본 데이터베이스 연결이 풀로 돌아가서 다른 호출자가 사용할 수 있습니다. 연결 풀링은 상당히 최적화되어 있으므로 그렇게해도 눈에 띄는 불이익이 없습니다. 조언은 기본적으로 트랜잭션과 동일합니다. 완료되면 짧고 가깝게 유지하십시오.

다중 연결을 사용하는 코드 주위에 단일 트랜잭션을 사용하여 MSDTC 문제가 발생하면 실제로 연결 개체를 공유하고 트랜잭션이 완료된 후에 만 ​​닫아야합니다.

그러나 여기서는 작업을 직접 수행하고 있으므로 DataSets, Linq to SQL, Entity Framework 또는 NHibernate와 같이 연결을 관리하는 도구를 조사 할 수 있습니다.


답변

면책 조항 : 이것이 오래되었다는 것을 알고 있지만이 사실을 쉽게 입증 할 수있는 방법을 찾았으므로 2 센트 가치를 투자하고 있습니다.

풀링이 실제로 더 빨라질 것이라고 생각하는 데 문제가있는 경우 다음을 시도해보십시오.

어딘가에 다음을 추가하십시오.

using System.Diagnostics;
public static class TestExtensions
{
    public static void TimedOpen(this SqlConnection conn)
    {
        Stopwatch sw = Stopwatch.StartNew();
        conn.Open();
        Console.WriteLine(sw.Elapsed);
    }
}

이제 모든 호출을 Open()로 바꾸고 TimedOpen()프로그램을 실행하십시오. 이제 각각의 고유 한 연결 문자열에 대해 콘솔 (출력) 창에 하나의 장기 실행 창이 열리고 매우 빠르게 열리게됩니다.

레이블 new StackTrace(true).GetFrame(1) +을 지정하려면에 대한 호출에 추가 할 수 있습니다 WriteLine.


답변

물리적 연결과 논리적 연결에는 차이가 있습니다. DbConnection은 일종의 논리적 연결이며 Oracle에 대한 기본 물리적 연결을 사용합니다. DbConnection을 닫거나 여는 것은 성능에 영향을주지 않지만 코드를 깨끗하고 안정적으로 만듭니다.이 경우 연결 누수가 불가능합니다.

또한 db 서버에서 병렬 연결에 대한 제한이있는 경우에 대해 기억해야합니다. 연결을 매우 짧게 만들어야한다는 점을 감안하면됩니다.

연결 풀을 사용하면 연결 상태를 확인하지 않아도됩니다. 연결 풀을 열고 사용하고 즉시 닫으면됩니다.


답변

일반적으로 각 트랜잭션에 대해 하나의 연결을 유지해야합니다 (병렬 계산 없음).

예를 들어 사용자가 청구 작업을 실행할 때 애플리케이션은 먼저 사용자의 잔액을 찾아 업데이트해야하며 동일한 연결을 사용해야합니다.

ado.net에 연결 풀이 있어도 디스패치 연결 비용은 매우 낮지 만 연결 재사용이 더 나은 선택입니다.

애플리케이션에서 하나의 연결 만 유지하지 않는 이유

일부 쿼리 또는 명령을 실행할 때 연결이 차단되기 때문에 응용 프로그램이 동시에 하나의 db 작업 만 수행하므로 성능이 얼마나 저하됩니다.

한 가지 더 문제는 사용자가 열려 있지만 작업이 없어도 응용 프로그램이 항상 연결된다는 것입니다. 많은 사용자가 응용 프로그램을 열면 db 서버는 곧 모든 연결 소스의 비용을 지불하지만 사용자는 연결하지 않습니다. 아무것도.


답변