2014-10-07 14 views
5

Tôi có một bảng MSSQL có chứa các tác vụ theo lịch trình mà dịch vụ Windows của tôi sẽ được xử lý dựa trên một dấu thời gian và tôi đã tự hỏi những gì lựa chọn thay thế tôi phải bỏ phiếu bảng như thế nàyThay thế cho bảng điểm bỏ phiếu MSSQL

SELECT * 
FROM mydb 
WHERE SYSUTCDATE() >= timestamp 

tôi d có thể cần phải thăm dò bảng ít nhất mỗi 5 giây. Về cơ bản tôi muốn Windows Service của tôi xử lý dữ liệu tại thời điểm được thiết lập bởi dấu thời gian trong bảng.

Đối với tôi, điều này có vẻ không phải là cách hiệu quả nhất. Tôi đã xem xét DML & trình kích hoạt CLR và tôi không nghĩ rằng chúng sẽ hoạt động khi chúng sẽ kích hoạt khi dữ liệu thay đổi và không khi dấu thời gian đã trôi qua. Suy nghĩ?


Cập nhật 2:

Tôi đã nhận ra rằng gọi đó là "dự kiến ​​nhiệm vụ" là một sự lựa chọn nghèo của từ ngữ vì vậy tôi sẽ cố gắng để mô tả nó một cách chi tiết hơn.

Mục tiêu của dự án này là gửi thông báo qua điện thoại cho mọi người tùy thuộc vào logic kinh doanh của chúng tôi. Một kịch bản là nhiều người nên được gọi điện vào những thời điểm cụ thể dựa trên một sự kiện nội bộ. Cùng một người có thể được gọi nhiều lần tùy thuộc vào cách cuộc gọi điện thoại được trả lời. Vì vậy, để đơn giản hóa mọi thứ và loại bỏ sự phức tạp và chi phí quản lý trạng thái của mỗi cuộc gọi điện thoại, tôi nghĩ nên lên lịch cho mỗi cuộc gọi điện thoại bằng cách đặt nó làm mục nhập trong bảng. Khi thông báo phải dừng lại, các cuộc gọi điện thoại đang chờ xử lý sẽ bị xóa khỏi bảng. Điều này sẽ giữ cho thiết kế của dịch vụ Windows rất đơn giản. Tất cả nó sẽ làm là gửi thông báo dựa trên dấu thời gian của nó trong bảng.


Cập nhật 1:

Message Queue

tôi đã không tìm ra cách người gửi sẽ đưa thông điệp vào hàng đợi tại thời điểm thích hợp.

SqlDependency

Tôi đang gặp một vấn đề bằng cách sử dụng mã ví dụ từ Detecting Changes with SqlDependency. Đối với một số lý do sự kiện OnChange chỉ bị sa thải ban đầu, không có gì xảy ra sau đó.

Cập nhật: Tôi không nghĩ SqlDependency sẽ hoạt động vì dữ liệu trong bảng sẽ không thay đổi để kích hoạt lửa.

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

Thay vào đó bạn đã cân nhắc sử dụng hàng đợi thư? – recursive

+3

Hãy thử SqlDependency: http://msdn.microsoft.com/en-us/library/62xk7953(v=vs.110).aspx –

+2

Bạn đã xem xét việc chuyển các công việc này thành công việc và chạy chúng thông qua SQL Server Agent? –

Trả lời

3

OK, trước hết, bạn không nên làm điều này. Việc tắt tất cả các công việc hữu ích cho các tác vụ định kỳ được cấu hình trong cơ sở dữ liệu là thiết kế dễ vỡ, dễ bị phá vỡ khi ai đó định cấu hình mọi thứ (dễ làm vì bạn cần trình kích hoạt khá tiên tiến để kiểm tra tính nhất quán của lịch biểu) và nó cũng có xu hướng tạo ra một hệ thống không thể hiểu được khi các tác vụ thực sự có các phụ thuộc ẩn (nếu A không chạy một thời gian trước khi B, công cụ ngắt, loại điều đó). Nguồn: kinh nghiệm cá nhân với ba hệ thống như vậy trong ba công ty khác nhau và ba nền tảng/công nghệ khác nhau và bằng cách nào đó tất cả họ đều phải chịu đựng những vấn đề tương tự, vì vậy dường như đó là một điều. Hãy xem xét việc chỉ viết những thứ bạn muốn lên lịch dưới dạng mã cũ đơn giản, với tệp cấu hình. Chắc chắn, nó sẽ không được như chung chung, nhưng những người phải duy trì nó sẽ cảm ơn bạn, đặc biệt là nhu cầu của họ trở nên phức tạp hơn.

SqlDependency khá thay đổi và không dễ sử dụng ngay cả khi bạn có truy vấn được hỗ trợ. Trong trường hợp của bạn, như bạn đã nhận thấy, nó không hoạt động vì công cụ cơ sở dữ liệu sẽ không đăng thông báo trừ khi dữ liệu thực sự thay đổi - không quan trọng là kết quả của truy vấn sẽ thay đổi khi thời gian trôi qua. Như Nick đã chỉ ra, việc bỏ phiếu cho một cơ sở dữ liệu cứ 5 giây một lần thường là tốt. Điều này tạo ra tải không đáng kể, miễn là bạn đã tạo chỉ mục trên mydb.timestamp (và bạn tạo điều này khá quan trọng, vì thực hiện quét bảng cứ sau 5 giây là không phải OK).

Phản đối duy nhất là độ trễ: nếu mọi cập nhật lịch biểu phải sớm hơn 5 giây một lần, việc bỏ phiếu không đủ tốt. Trong trường hợp này, bạn có thể sử dụng Nhà môi giới dịch vụ và đăng thông báo lên hàng đợi ngay khi có thay đổi gì đó (có thể từ trình kích hoạt). Trên thực tế, SqlDependency sử dụng cùng một cách tiếp cận dưới bìa, vì vậy bạn có thể tạo phụ thuộc vào SELECT * FROM table để nhận thông báo bất cứ khi nào thay đổi bất kỳ điều gì trong bảng và sau đó thực hiện truy vấn thực tế để nhận những gì bạn cần (có thể tìm ra không có gì). Hãy cẩn thận, mặc dù: nhận được mã cho chính xác này mà không bị nhầm lẫn bởi nhiều cập nhật nhanh chóng hoặc phá vỡ kết nối không phải là tầm thường và có lẽ không có giá trị nó, như trái ngược với chỉ tải lại định kỳ.

+0

Cảm ơn bạn đã phản hồi chi tiết. Lý do của tôi để lên kế hoạch cho tất cả các nhiệm vụ trong cơ sở dữ liệu là vì tôi nghĩ nó sẽ đơn giản hóa mọi thứ vì sẽ có quá nhiều chi phí để quản lý nó theo chương trình. Tôi sẽ cung cấp thêm thông tin trong OP của tôi. – user3811205

Các vấn đề liên quan