2012-01-14 2 views
1

"시간 초과가 만료되었습니다. 풀에서 연결을 얻기 전에 제한 시간이 경과했습니다. 풀링 된 모든 연결이 사용 중이기 때문에이 문제가 발생할 수 있습니다. 최대 풀 크기에 도달했습니다. " 오류는 있지만 문제가있는 곳을 찾을 수 없습니다. 좀 도와주세요. :)제한 시간 만료 Exception; 어떤 연결이 열려 있는지 또는 다른 것이 틀린 경우 찾을 수 없음

public static void Update(string p, int c) 
    { 
     using (SqlConnection conn = new SqlConnection("ConnectionString")) 
     { 
      SqlCommand cmd = new SqlCommand(); 
      SqlDataReader myRdr; 

      cmd.Connection = conn; 
      cmd.CommandText = "SOME SQL QUERY @parameter"; 
      cmd.CommandType = CommandType.Text; 
      cmd.Parameters.Add("@parameter", SqlDbType.NVarChar, 10).Value = p; 

      conn.Open(); 
      myRdr = cmd.ExecuteReader(); 

      if (myRdr.HasRows) 
      { 
       while (myRdr.Read()) 
       { 
        //do something using myRdr data 
       } 
       myRdr.Close(); 
       cmd.Dispose(); 

       foreach (DataRow r in dt.Rows) 
       { 
        SqlCommand cmd1 = new SqlCommand(); 

        cmd1.Connection = conn; 
        cmd1.CommandText = "SOME SQL QUERY @parameter"; 
        cmd1.CommandType = CommandType.Text; 
        cmd1.Parameters.Add("@parameter", SqlDbType.NVarChar, 10).Value = r["SomeData"]; 

        myRdr = cmd1.ExecuteReader(); 
        myRdr.Read(); 

        //do something with myRdr data 

        myRdr.Close(); 
        cmd1.Dispose(); 

        int a = Convert.ToInt32(r["SomeData"]) - Convert.ToInt32(r["SomeData1"]); 

        if (a >= 0) 
        { 
         //do something 
        } 
        else 
        { 
         //do something else and runn the Update() again with some other parameters 

         Update(x, y); //I think here is some problem... 
             //because when this condition is not met and program 
             //does not need to run Update() again, it goes OK and I get no error 
        } 
       } 
      } 
      else 
      { 
       myRdr.Close(); 
       cmd.Dispose(); 
      } 
     } 
    } 

답변

3

당신은 어딘가에 외부 using() 블록 외부 Update(x,y)에 전화를 이동 cosider한다.

내부에서 호출하는 경우 using은 외부 데이터베이스를 먼저 해제하지 않고 동일한 데이터베이스에 다른 연결을 설정한다는 것을 의미합니다. 재귀 호출 수가 많으면 무료 연결이 매우 빨리 끊깁니다.

일반적으로 데이터베이스를 다루는 코드 부분에서 재귀 호출을 사용하는 것은 매우 나쁜 습관으로 간주됩니다.

여기에이 재귀가 실제로 필요한 경우 여전히 바깥 쪽 using 외부에서 수행해야합니다. 나는 수집의 어떤 종류에 x,y 캐싱이처럼 using 블록 외부에서이 컬렉션을 통과하여 Update(x,y)에 호출을 실행하는 것이 좋습니다 것 :

public static void Update(string p, int c) 
{ 
    // I'd suggest Dictionary, but don't know whether your strings are unique 
    var recursionParameters = new List<KeyValuePair<string, int>>(); 

    using (SqlConnection conn = new SqlConnection("ConnectionString")) 
    { 
     ... 
        //do something else and runn the Update() again with some other parameters 

        //Update(x, y); Don't do it here! Instead: 
        recursionParameters.Add(new KeyValuePair<string, int>(x,y)); 
     ... 
    } 
    foreach (var kvp in recursionParameters 
    { 
     Update(kvp.Key, kvp.Value) 
    } 
} 
+0

특정 조건이 충족 될 때 Update()를 호출해야합니다. 어디에서 전화를해야합니까? 나는 그것을하는 다른 쉬운 방법을 모른다. 하지만 나는 초보자입니다. :) 도움? ;) – user1080533

+0

몇 가지 코드로 내 대답을 업데이트했습니다. –

+0

덕분에, 내 자신의 구문을 이해하려고 노력하면서 시간을 절약 해주었습니다 :) – user1080533

1

귀하의 예외가 발생했을 때 Reader이 종료되지 않을 수 있습니다. 마침내 블록으로 둘러 싸서 예외를 만났을 때 독자는 finally 문을 닫을 것입니다.

try 
{ 
    myRdr = cmd.ExecuteReader(); 
    // do some other stuff 
} 
catch(SqlException) 
{ 
    // log the exception or deal with ex. 

} 
finally 
{ 
    myRdr.Close(); // you can be sure it will be closed even on exception 

} 
+0

try와 finrally 블록을 사용하여 도움이되는지 확인합니다. :) – user1080533

관련 문제