2009-06-29 8 views
0

나는 백그라운드 타이머에서 매초마다 호출되는 정적 읽기 메서드로 C# 데이터베이스 계층을 사용합니다.데이터베이스 작업 모범 사례?

현재 저는 SqlCommand, SqlConnection을 한 번 클래스 구성원으로 만듭니다.

모든 메서드 호출에서 결과를 얻기 위해 명령을 실행합니다. 연결 및 명령을 매 초마다 생성하지 않으려 고합니다. 그러나이 메서드에서 예외가 발생하여 연결이 끊어 지거나 개체가 배치되는 것이 두렵습니다. 무효 상태.

이 내 현재의 구현 (타이머 핸들러)

static void GetBarTime(object state) 
    { 
     lock (_staticConnection) 
     { 
      SqlDataReader dataReader = null; 
      try 
      { 
       dataReader = _getMaxTimeCommand.ExecuteReader(); 
       dataReader.Read(); 
       _currentTick = dataReader.GetInt32(0); 
      } 
      catch (Exception ex) 
      { 
       //Log the error 
      } 
      finally 
      { 
       dataReader.Dispose(); 
      } 
     } 
    } 

가장 좋은 방법은 무엇입니까?

상세 정보 : 다른 prorcess 초마다 내 테이블을 업데이트가, 클라이언트의 설정에 의해 사용되는 최신 값을 얻기 위해 매 초마다 불리는 또 다른 노출 방법이 있으므로 내가 타이머에이 일을하고

.

그래서 각 클라이언트에 대해 매 초마다 select 문을 실행하는 대신 클라이언트에서 사용하는 전역 변수 및 타이머를 업데이트하고 있습니다.

+0

당신이 시나리오를 설명 할 수 DB에서 일을 읽으려면 타이머에 코드를 작성해야합니까? DB 값은 얼마나 자주 변경됩니까? – shahkalpesh

+0

세부 사항을 추가했습니다. –

+0

(의견에 회신) –

답변

2

SqlConnection에는 풀링이 내장되어 있습니다. 다음과 같이 사용하면 거의 차이가 없습니다.

using(SqlConnection conn = new SqlConnection(connectionString)) { 
    conn.Open(); 
    // your code 
} 

그리고 그것은 자동으로 죽은 (근본적인) 연결에 반응 할 수 있습니다.

현재 버그가 있습니다. btw; 명령이 실패하면, 독자는 여전히 null이 될 것입니다 ... 하나 Dispose()를 호출하기 전에 null 확인 :

if(dataReader !=null) {dataReader.Dispose();} 

을하거나 using 사용 : 당신이 이유에,

try 
{ 
    using(SqlDataReader dataReader = _getMaxTimeCommand.ExecuteReader()) 
    { 
     dataReader.Read(); 
     _currentTick = dataReader.GetInt32(0); 
    } 
} 
catch (Exception ex) 
{ 
    //Log the error 
} 
+0

좋지만 로직에 대해서는 각 호출에 대해 연결 및 명령을 작성하는 것이 더 좋습니까? –

+0

보통 예, 통화 당 더 좋습니다. 상태 관리/스레딩/기타 문제에는 아무런 문제가 없습니다. 또한 명령이 어떻게 생겼는지에 따라 달라집니다. 예를 들어 저장 프로 시저가 준비된 명령을 유지하는 데 실질적인 이점을 갖지는 않습니다. –

+0

나는 일반적인 경우를 요구하지 않는다. 매 초마다 호출되는 메쏘드에 대해 연결 풀이 있다는 것을 알지만, 매번 호출 할 때마다이 메도의 전용 연결을 비교하는 데 약간의 시간이 걸린다. –

1

실행이 연결이 죽은 오리임을 의미하는지 알아내는 것은 꽤 어려울 수 있습니다. 안전한 경우를 대비하여 예외가 발생할 때마다 SqlConnection 및 SqlCommand를 닫았다가 다시 열 수 있습니다. 모든 것이 올바르게 작동하면 오버 헤드가 발생하지 않습니다.

+0

그래서 동일한 코드를 사용할 수 있습니다. 다만 예외 처리에서 닫고 다시 연결을 열어 볼 수 있습니까? –

+0

IMO better : 예외 처리기에서이를 닫고 null로 설정하십시오. GetBarTime에서 lock() 블록에서 연결이 null인지 확인하십시오. 있는 경우 열어서 SqlStatement를 작성하십시오. 이렇게하면 데이터베이스가 잠시 동안 사용할 수 없을 때 문제를 피하는 것이 더 쉬워집니다. –

+0

(계속) 무언가 예외가 발생하면 연결을 다시 열어도 실패 할 수 있기 때문에 ... –

관련 문제