ADO.NET을 사용하면 Connection Leak이 발생하는 경우가 종종 있다. 그 중의 한 케이스가 SqlDataReader을 사용할 때
흔히 발생한다. 예를 들어, 아래의 예 처럼 SqlDataReader를 리턴하는 메서드를 만든 후 이를 호출해서 사용하는 경우가 많다.
이 경우
SqlConnection 객체는 GetDataReader() 메서드를 빠져 나가면 그 SqlConnection 객체를 엑세스할 방법이 없어 진다.
나중에 SqlDataReader객체에서 SqlDataReader.Close() 를 호출한다 해도 이는 DataReader만 Close하기 때문에 Connection을 닫을 수 없게 된다.
즉, Connection Leak이 일어나는 것이다. 이러한 문제를 해결하는 방법은 ExecuteReader 메서드를 실행할 때
CommandBehavior.CloseConnection 옵션을
아래 예와 같이 주는 것이다. 이 옵션을 사용하면 SqlDataReader.Close()가 호출되었을 때, SqlConnection도 같이 Close된다.
예제
// SqlDataReader 객체를 리턴
public SqlDataReader GetDataReader()
{
SqlConnection conn = new SqlConnection(strConn);
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT * FROM Production.Product";
SqlDataReader rdr = cmd.ExecuteReader();
return rdr;
}
// SqlDataReader를 사용후 Close
private void button1_Click(object sender, EventArgs e)
{
MySample sample = new MySample();
SqlDataReader dr = sample.GetDataReader();
dr.Read();
data = dr[0].ToString();
dr.Close();
}
// 문제점 해결 방법:
// System.Data.CommandBehavior.CloseConnection
SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);