2011-12-19 4 views
1

24/7을 실행해야하는 시스템을 제어하는 ​​타이머가 있습니다. 데이터베이스에 대한 호출이 많으며 어느 시점에 두 개의 메소드가 연결을 열려고 시도하는 중 하나가 실패합니다. 재 시도 메서드를 만들려고 했으므로 메서드가 성공할 것입니다. Better way to write retry logic without goto 마이클 S. Scherotter 스티븐 Sudit의 방법의 도움으로, 내 방법은 다음과 같이 않습니다데이터베이스를 다시 호출하는 방법

 int MaxRetries = 3; 
     Product pro = new Product(); 
     SqlConnection myCon = DBcon.getInstance().conn(); 

     string barcod = barcode; 

     string query = string.Format("SELECT * FROM Product WHERE Barcode = @barcode"); 

     for (int tries = MaxRetries; tries >= 0; tries--) //<-- 'tries' at the end, are unreachable?. 
     { 
      try 
      { 

       myCon.Open(); 
       SqlCommand com = new SqlCommand(query, myCon); 
       com.Parameters.AddWithValue("@barcode", barcode); 
       SqlDataReader dr = com.ExecuteReader(); 
       if (dr.Read()) 
       { 
        pro.Barcode = dr.GetString(0); 
        pro.Name = dr.GetString(1); 
       } 

        break; 
       } 
       catch (Exception ex) 
       { 
        if (tries == 0) 
         Console.WriteLine("Exception: "+ex); 
         throw; 

       } 
       } 



     myCon.Close(); 
     return pro; 

코드를 실행, 프로그램 "에 대한 (.....)"를 정차, 및 예외 : 연결이 닫히지 않았습니다. 연결의 현재 상태가 열려 있습니다 ...이 문제는 내가이 메서드를 만들기 위해 노력하는 이유입니다! 누구든지이 문제를 해결하는 방법을 알고 있다면 작성하십시오. 감사합니다

답변

0

편집 새로운 정보에 대한

방법에 대한 트랜잭션을 사용하여 데이터 무결성을 보존하고 여러 액세스에 대한 직접 연결을 가져온 다음 연결 문이 닫혀 있는지 확인하기 위해 문을 사용하여 래핑합니다. 연결이 사용하는 문장의 끝 부분에 도달 할 때 예를 들어

 Using (SqlConnection myCon = new SqlConnection('ConnectionString')) 
     { 
      myCon.Open(); 
      var transaction = myCon.BeginTransaction();  
      try 
      { 
      // ... do some DB stuff - build your command with SqlCommand but use your transaction and your connection 
      var sqlCommand = new SqlCommand(CommandString, myCon, transaction); 
      sqlCommand.Parameters.Add(new Parameter()); // Build up your params 
      sqlCommand.ExecuteNonReader(); // Or whatever type of execution is best 
      transaction.Commit(); // Yayy! 
     } 
     catch (Exception ex) 
     { 
      transaction.RollBack(); // D'oh! 
      // ... Some logging 
     } 

     myCon.Close(); 
    } 

당신이 연결을 종료하는 것을 잊지 경우에도이 방법은 여전히 ​​암시 적으로 수행됩니다.

+0

을 잘 이해하고 어떤 점은 이해하지 못합니다. 이미 연결에 싱글 톤을 사용하고 있습니다. 결국이 방법뿐만 아니라 연속 방법을 사용하여 데이터베이스에 연결하는 20 가지 방법을 사용할 수 있으므로 결국에는 두 가지 방법이 동시에 연결됩니다. – WildBoar

+0

흥미로운 점은 시스템이 별도의 스레드/인스턴스에서 실행되고 있습니까? 그렇지 않다면 싱글 톤을 팩토리 클래스로 대체하고 새로운 데이터베이스 연결을 전달하면된다. 콜리 전이 없다. –

+0

그들은 개별 인스턴스에서 실행 중입니다. – WildBoar

2

당신은

myCon.Open(); 
루프 내부

하지만

myCon = DBcon.getInstance().conn(); 

그것의 외부에서이를 수행. 이렇게하면 동일한 연결을 여러 번 열려고 시도합니다. 당신은 DB 연결의 손실을 방지하려면 당신은

0

당신이 Finally 블록으로

myCon.Close(); 

를 추가하는 시도 가지고 TEH 루프 안에 모두 넣어해야합니다. 예외가있는 경우 절대 공격을받지 않는 것 같습니다. 나는 당신이 연결, 명령 객체 등을 Using 문장에 감쌀 것을 강력히 권고한다. 이렇게하면 제대로 처리되고 연결이 닫힙니다.

당신은 문 외부 myCon.Open에 전화를 이동하거나 다시 열기 연결하기 전에 연결 상태를 확인) (myCon.Open을 포장한다
+0

finally 블록을 사용해 보았지만 그 중 하나가 작동하지 않았습니다. 어느 시점에서 – WildBoar

1

:

if (myCon.State != ConnectionState.Open) 
{ 
    myCon.Open(); 
} 
관련 문제