연결을 닫았다가 다시 열어야 할 이유는 없습니다. 데이터베이스와 네트워크에 불필요한 로드를 부과합니다.
커넥션 풀링에 관해 알아보겠습니다.
원래 질답란에 있던 내용인데, 일반적이지 않은 내용이어서 정리를 해서 일반적인 사용법을 알려드리겠습니다.
커넥션 풀링은 DB와의 새 연결시 많은 자원을 소모하는 데, 직접연결을 피하고, 연결된 커넥션을 자원으로서 관리를 하여 성능향상을 얻고자 하는 방법입니다.
다시 설명하면,
풀링매니저가, 연결된 커넥션을 자원으로 관리를 하면서, 어플리케이션에서 필요로 할 때 리소스가 많이 필요한 새연결을 하지 않고, 기존 자원으로 재사용을 하고, 연결 끊기문장을 만났을 때 DB와의 실제 연결을 끊지 않고, 풀링에 반납함으로써, DB와의 연결과 끊기를 실제적으로 줄여주는 효과가 있습니다.
1) 풀링의 생성
어플리케이션에는 한개이상의 커넥션 풀링이 존재할 수 있습니다. 이 각각의 커넥션 풀링은 특정한 connection string에 관계가 있습니다.
최초에 커넥션이 닫힐 때, 특정한 connection string을 가진 커넥션 풀이 생성됩니다. 그리고 연결은 실질적으로 끊지 않습니다. (풀을 사용하던 안하던 최초엔 풀에서 커넥션을 만들지 않음)
그후 새로운 커넥션이 생성이 될 때, connection string 이 기존 풀의 connection string과 다르면, 커넥션이 닫힐 때 새로운 pool이 생성됩니다. 이때 만약 똑같은 connection string 을 사용한다면 새로운 풀이 생성되지 않고 기존의 커넥션을 이용합니다.
이를 소스로서 예를 들어보면.
SqlConnection conn = new SqlConnection();
conn.ConnectionString = "Integrated Security=SSPI;Initial Catalog=northwind";
conn.Open();
// Pool A 가 생성됨
SqlConnection conn = new SqlConnection();
conn.ConnectionString = "Integrated Security=SSPI;Initial Catalog=pubs";
conn.Open();
// Pool B 가 생성됨 (connection string이 다르다)
SqlConnection conn = new SqlConnection();
conn.ConnectionString = "Integrated Security=SSPI;Initial Catalog=northwind";
conn.Open();
// Pool A의 자원을 이용한다. connection string 이 Pool A와 일치.
여기에선 모두 3개의 connection 객체가 생성되었지만, 2개의 connection pool이 생성되었다.풀이 일단 한번 생성되면, 프로세스가 종료할 때가지 사라지지 않고 지속된다. 비어있는 풀은 최소한의 오버헤드를 야기한다.
2) 커넥션관련 추가사항
커넥션은 한번 생성되면 minimum pool size가 충족될때까지 connection 이 풀링된다.
만약 sqlconnection이 요청되면, 풀에서 사용가능한 커넥션이 얻어진다. 만약 maximum pool size에 도달하여, 사용가능한 커넥션이 없다면 풀에서 자원이 반납될 때까지 기다린다. time-out 기간까지 얻어내지 못하면, 에러가 발생한다.
3) 주의사항
반드시 connection을 사용후에는 반납을 해야한다.
반납은 close() 나 dispose()를 통해 가능하다. nothing은 할 필요는 없다.
반납을 명시적으로 하지 않게 되면, 풀에 자원반납이 되지 않는다.
4) connection pool관련 keyword
Pooling : 기본값 'true' : 이것을 false로 하면, 풀링이 사용되지 않는다. 즉 open()시 직접 DB를 열고, close()시 닫는다.
Max Pool Size : 기본값 100 : 최대 풀링사이즈
Min Pool Size : 기본값 0 : 최소 풀링사이즈
Connection Lifetime : 기본값 0(초) : 이것은 풀내에서 커넥션들의 lifetime이다.
5) 사용예
보통 커넥션 스트링에
con.ConnectionString = "data source=xxx.xxx.xxx.xxx; initial catalog=nothwinds;user id=sa;password="
이렇게 쓰신다면, 풀링을 사용하시는 겁니다.왜냐하면, Pooling=true 가 디폴트 값이니까요..
con.ConnectionString = "data source=xxx.xxx.xxx.xxx; initial catalog=nothwinds;user id=sa;password=, Pooling='true''"
이것과 같은 의미입니다. 또한 Max Pool Size 속성이 디폴트값이 100 이므로
con.ConnectionString = "data source=xxx.xxx.xxx.xxx; initial catalog=nothwinds;user id=sa;password=, Pooling='true'', Max Pool Size=100"
이것도 같은 의미입니다.
6) 기타
퍼포먼스 카운터를 이용하면, 현재 풀의 사이즈를 실시간으로 조사할 수 있습니다.
퍼포먼스 카운터는 관리도구-> 성능 탭으로 이용합니다.
그중에서 ".NET CLR Data" performance object 를 선택하여서 보면 다음과 같은 항목을 확인 할 수 있습니다
◈ DB로부터 값을 가져오는 방식
1) 연결지향형
연결지향형은 DataReader를 사용
2) 비연결지향형
비연결지향형은 DataAdapter를 사용
DataAdapter를 사용하실 경우 실행하신 쿼리에 대한 결과값을 한번에 DataSet에 밀어넣으실 수 있습니다.
따라서 결과적으로 보면 쿼리에 대한 결과를 쫙 긁어오고 바로 닫는 그런 식이죠...
DataReader는 사용하시는 동안은 항상 연결이 유지되어야 합니다.
보통 DataReader는 다음과 같이 사용합니다.
conn.Open();
cmd.CommandText = "select * from tabs";
SqlDataReader dr = cmd.ExecuteDataReader();
if (dr != null)
{
while (dr.Read())
{
// 처리
}
dr.Close();
}
conn.Close();
이런식입니다.. 아니면 ExcuteDataReader 메소드의 파라메터로 DataReader 객체를 닫으면 DB 커넥션을
같이 끊는 옵션을 제공해 주는 것으로 알고있습니다.
'C#' 카테고리의 다른 글
[C#] DB Connection Pooling (0) | 2018.07.25 |
---|---|
[C#] 요점정리 (0) | 2018.07.16 |
[C#] 배열 복사 (0) | 2018.07.16 |
[C#] Thread(스레드) (0) | 2018.07.16 |
[C#] Naming 규칙 (0) | 2018.07.16 |