대안

2014-10-07 5 views
5

가 나는 폴링에 나는 '이대안

SELECT * 
FROM mydb 
WHERE SYSUTCDATE() >= timestamp 

같은 테이블이 어떤 대안을 내 Windows 서비스는 타임 스탬프를 기반으로 처리해야 내가 궁금해서 예약 된 작업을 포함하는 MSSQL 테이블이 아마도 적어도 매 5 초마다 테이블을 폴링해야 할 것입니다. 기본적으로 테이블의 타임 스탬프로 설정된 시간에 Windows 서비스가 데이터를 처리하기를 원합니다.

나에게 이것은 가장 효과적인 방법처럼 보이지 않습니다. 나는 이미 DML & CLR 트리거를 조사해 보았습니다. 데이터가 바뀌면 타임 스탬프가 지났을 때와 달리 작동하지 않을 것이라고 생각합니다. 생각?


업데이트 2 :

내가 더 자세히 그것을 설명하려고합니다 그래서 전화 "예약 된 작업"표현의 빈약 한 선택 이었다는 것을 깨달았다.

이 프로젝트의 목표는 비즈니스 로직에 따라 사람들에게 전화 알림을 전송하는 것입니다. 한 시나리오는 내부 이벤트를 기반으로 특정 시간에 여러 사람이 전화를해야한다는 것입니다. 전화를받는 방법에 따라 같은 사람을 여러 번 호출 할 수 있습니다. 따라서 사물을 단순화하고 각 전화 상태를 관리하는 복잡성과 오버 헤드를 제거하기 위해 각 전화 통화를 테이블에 입력하여 사전 예약하는 것이 좋습니다. 알림을 중지해야하는 경우 보류중인 전화가 테이블에서 삭제됩니다. 이렇게하면 Windows 서비스의 디자인을 매우 간단하게 유지할 수 있습니다. 모든 작업은 테이블의 타임 스탬프를 기반으로 알림을 보냅니다.


업데이트 1 :

Message Queue는

내가 보낸 사람이 적절한 시간에 큐에 메시지를 넣어하는 방법을 알아 냈하지 않았습니다.

SqlDependency

내가 Detecting Changes with SqlDependency에서 예제 코드를 사용하여 문제가 발생하고있다. 어떤 이유로 OnChange 이벤트는 처음에만 시작되며 이후에는 아무 것도 발생하지 않습니다.

업데이트 : 테이블의 데이터가 트리거 실행을 변경하지 않으므로 SqlDependency가 작동하지 않을 것이라고 생각합니다.

void Initialization() 
{ 
    // Create a dependency connection. 
    SqlDependency.Start(connectionString, queueName); 
} 

void SomeMethod() 
{ 
    // Assume connection is an open SqlConnection. 

    // Create a new SqlCommand object. 
    using (SqlCommand command=new SqlCommand(
     "SELECT timestamp,othercolumn FROM mydb WHERE SYSUTCDATE() >= timestamp", 
     connection)) 
    { 

    // Create a dependency and associate it with the SqlCommand. 
    SqlDependency dependency=new SqlDependency(command); 
    // Maintain the refence in a class member. 

    // Subscribe to the SqlDependency event. 
    dependency.OnChange += new OnChangeEventHandler(OnDependencyChange); 

    // Execute the command. 
    using (SqlDataReader reader = command.ExecuteReader()) 
    { 
     // Process the DataReader. 
    } 
} 
+7

대신 메시지 대기열을 사용 해본 적이 있습니까? – recursive

+3

SqlDependency 시도 : http://msdn.microsoft.com/en-us/library/62xk7953(v=vs.110).aspx –

+2

이러한 작업을 SQL Server 에이전트를 통해 작업으로 바꾸는 것이 좋습니다. –

답변

3

좋습니다. 우선이 작업을 전혀 고려하지 마십시오. 모든 유용한 작업을 데이터베이스에 구성된주기적인 작업으로 전환하는 것은 깨지기 쉬운 디자인입니다. 누군가가 잘못 구성하면 쉽게 깨지는 경향이 있습니다 (일정 일관성을 확인하기 위해 고급 트리거가 필요하기 때문에 쉽게 수행 할 수 있음). 작업이 실제로 숨겨진 종속성을 가지고있을 때 이해할 수없는 시스템을 만듭니다 (A가 B, 물건 중단, 그런 종류의 것보다 전에 실행되지 않은 경우). 출처 : 3 개의 다른 회사와 3 개의 다른 플랫폼/기술에서 3 개의 시스템을 사용한 개인적인 경험. 어떻게 든 그들은 모두 동일한 문제로 어려움을 겪었습니다. 구성 파일을 사용하여 일반 오래된 코드로 일정을 잡기 만하면됩니다. 물론, 일반적이지는 않지만, 유지해야하는 사람들, 특히 그들의 요구가 더욱 복잡해지면서 당신에게 감사 할 것입니다.

SqlDependency은 지원되는 검색어가 있어도 변덕스럽고 사용하기 쉽지 않습니다. 귀하가 알고 계시 듯이, 데이터베이스 엔진은 데이터가 실제로 변경되지 않는 한 알림을 게시하지 않으므로 작동하지 않습니다. 시간이 지남에 따라 쿼리 결과가 변경되는 것은 중요하지 않습니다. Nick이 지적했듯이, 5 초마다 데이터베이스를 폴링하는 것이 일반적으로 좋습니다. mydb.timestamp에 색인을 작성한 경우 5 초마다 표 스캔을 수행하면 이 아니라이 아니기 때문에이 값을 생성하는 것이 중요합니다.이 경우 무시할 수있는로드가 생성됩니다.

유일하게 이의가 있습니다. 일정에 대한 업데이트가 5 초마다 한 번 이상 발생하면 폴링이 충분하지 않습니다. 이 경우 Service Broker를 사용하여 무언가가 변경되는 즉시 트리거에 알림을 큐에 게시 할 수 있습니다. 사실, SqlDependency은 커버 아래에서 동일한 접근법을 사용하므로 이 테이블에서 변경 될 때마다 알림을 받고 실제 쿼리를 수행하여 필요한 것을 얻을 수 있습니다 (아마도 아무것도 발견하지 못할 수도 있음).). 그러나 여러 개의 빠른 업데이트 또는 연결 끊김으로 인해 혼동되지 않고이 코드를 올바르게 작성하는 것은 주기적으로 다시로드하는 것과는 대조적으로 그다지 가치가 없으며 사소한 것이 아닙니다.

+0

자세한 답변을 보내 주셔서 감사합니다. 데이터베이스의 모든 작업을 미리 스케줄링하는 이유는 프로그래밍 방식으로 관리하기에는 너무 많은 오버 헤드가 있으므로 작업을 단순화 할 것이라고 생각했기 때문입니다. 나는 나의 OP에서 더 많은 정보를 제공 할 것이다. – user3811205