2010-01-28 22 views
14

Tôi có yêu cầu giám sát các hàng Cơ sở dữ liệu liên tục để kiểm tra các Thay đổi (cập nhật). Nếu có một số thay đổi hoặc cập nhật từ các nguồn khác, sự kiện sẽ được kích hoạt trên ứng dụng của tôi (tôi đang sử dụng WCF). Có cách nào để nghe hàng cơ sở dữ liệu liên tục cho những thay đổi không?C#/Trợ giúp trình nghe cơ sở dữ liệu SQL cần

Tôi có thể có nhiều sự kiện hơn để theo dõi các hàng khác nhau trong cùng một bảng. là có bất kỳ vấn đề trong trường hợp hiệu suất. Tôi đang sử dụng dịch vụ web C# để theo dõi kết thúc của SQL Server.

Trả lời

5

Tôi đã có một yêu cầu rất giống thời gian trước đây và tôi đã giải quyết nó bằng cách sử dụng CLR SP để đẩy dữ liệu vào hàng đợi thư. Để dễ dàng triển khai, tôi đã tạo một CLR SP với một chức năng nhỏ xíu gọi là SendMessage vừa đẩy một thông điệp vào Hàng đợi Tin nhắn và gắn nó vào các bảng của tôi bằng trình kích hoạt INSERT SAU (kích hoạt bình thường, không kích hoạt CLR) .

Hiệu suất là mối quan tâm chính của tôi trong trường hợp này, nhưng tôi đã căng thẳng thử nghiệm nó và nó vượt quá mong đợi của tôi. Và so với SQL Server Service Broker, nó là một giải pháp rất dễ triển khai. Mã trong CLR SP thực sự là tầm thường.

9

Bạn có thể sử dụng trình kích hoạt CẬP NHẬT SAU trên các bảng tương ứng để thêm một mục vào hàng đợi SQL Server Service Broker. Sau đó, có các thông báo xếp hàng được gửi đến dịch vụ web của bạn.

Một poster nêu SqlDependency, mà tôi cũng nghĩ đến việc nhắc đến nhưng tài liệu MSDN là một chút kỳ lạ ở chỗ nó cung cấp một ví dụ cửa sổ khách hàng mà còn đưa ra lời khuyên này:

SqlDependency được thiết kế để được sử dụng trong các dịch vụ ASP.NET hoặc trung cấp nơi có một số máy chủ tương đối nhỏ có phụ thuộc hoạt động đối với cơ sở dữ liệu. Đó là không được thiết kế để sử dụng trong ứng dụng khách , trong đó hàng trăm hoặc hàng nghìn máy khách sẽ có đối tượng SqlDependency được thiết lập cho một máy chủ cơ sở dữ liệu duy nhất.

Ref.

+0

Trong trường hợp của tôi, tôi không có quyền truy cập trực tiếp vào cơ sở dữ liệu nhưng truy cập vào các bảng trong Cơ sở dữ liệu. Hàng đợi Nhà môi giới sẽ có ý nghĩa trong trường hợp của tôi không? Những gì tôi cần là một cách để sắp xếp cuộc thăm dò các bảng cụ thể cho các thay đổi (chèn, cập nhật, xóa) và kích hoạt một sự kiện như là kết quả của việc xử lý tiếp theo diễn ra sau đó. Tôi đã suy nghĩ về ý tưởng của một hàm CLR hoặc một loại sắp xếp gọi dịch vụ sau khi chèn/cập nhật/xóa dữ liệu thành công từ các bảng. Điều đó có tốt trong tình huống này không? – Kobojunkie

+0

để viết SQL-CLR bạn cần truy cập trực tiếp vào cơ sở dữ liệu. Trong thực tế, bạn đang mâu thuẫn với chính mình ?! –

2

Giám sát "liên tục" có thể có nghĩa là sau vài giờ, phút, giây hoặc thậm chí là mili giây. Giải pháp này có thể không hoạt động đối với các bản cập nhật phần nghìn giây: nhưng nếu bạn chỉ phải "giám sát" một bảng một vài lần trong một phút, bạn có thể chỉ cần có một quy trình bên ngoài kiểm tra một bảng để cập nhật. (Nếu có cột DateTime hiện tại.) Sau đó bạn có thể xử lý các hàng đã thay đổi hoặc mới được thêm vào và thực hiện bất kỳ thông báo nào bạn cần. Vì vậy, bạn sẽ không được lắng nghe những thay đổi, bạn sẽ được kiểm tra cho họ. Một lợi ích của việc kiểm tra theo cách này sẽ là bạn sẽ không mạo hiểm nhiều hiệu suất trúng nếu nhiều hàng được cập nhật trong một lượng thời gian nhất định kể từ khi bạn gộp chúng lại với nhau (trái ngược với việc trả lời từng và mọi thay đổi cá nhân.)

2

tôi suy nghĩ ý tưởng của một hàm CLR hay cái gì đại loại mà các cuộc gọi các dịch vụ sau thành công chèn/cập nhật/xóa dữ liệu từ các bảng. Đó có phải là tốt trong tình huống này không?

Có lẽ đó không phải là ý tưởng hay, nhưng tôi đoán nó vẫn tốt hơn là vào địa ngục kích hoạt bảng.

Tôi cho rằng vấn đề của bạn là bạn muốn làm điều gì đó sau mỗi lần sửa đổi dữ liệu, giả sử, tính toán lại một số giá trị hoặc bất kỳ giá trị nào. Để cơ sở dữ liệu chịu trách nhiệm về điều này không phải là một ý tưởng tốt bởi vì nó có thể có tác động nghiêm trọng đến hiệu suất.

Bạn đã đề cập đến bạn muốn phát hiện chèn, cập nhật và xóa trên các bảng khác nhau. Làm theo cách bạn đang hướng tới, điều này sẽ yêu cầu bạn thiết lập ba hàm trigger/CLR trên mỗi bảng và yêu cầu họ đăng sự kiện lên WCF Service (thậm chí được hỗ trợ trong tập con của .net có sẵn bên trong máy chủ sql?). Dịch vụ WCF thực hiện các hành động thích hợp dựa trên các sự kiện đã nhận được.

Giải pháp tốt hơn cho vấn đề sẽ là di chuyển trách nhiệm phát hiện sửa đổi dữ liệu từ cơ sở dữ liệu của bạn sang ứng dụng của bạn. Điều này thực sự có thể được thực hiện rất dễ dàng và hiệu quả.

Mỗi bảng có khóa chính (int, GUID hoặc bất kỳ thứ gì) và cột dấu thời gian, cho biết thời điểm mục nhập được cập nhật lần cuối. Đây là một thiết lập bạn sẽ thấy rất thường xuyên trong các tình huống đồng thời lạc quan, vì vậy thậm chí có thể không cần thiết phải cập nhật các định nghĩa lược đồ của bạn. Mặc dù, nếu bạn cần thêm cột này và không thể tải xuống dấu thời gian cho ứng dụng bằng cách sử dụng cơ sở dữ liệu, bạn chỉ cần viết một kích hoạt cập nhật cho mỗi bảng, cập nhật dấu thời gian sau mỗi lần cập nhật.

Để phát hiện sửa đổi, ứng dụng giám sát/dịch vụ WCF của bạn xây dựng một từ điển cục bộ (tốt nhất là một hashtable) với các cặp khóa/dấu thời gian chính tại một khoảng thời gian nhất định. Sử dụng chỉ mục vùng phủ sóng trong cơ sở dữ liệu, thao tác này sẽ rất nhanh. Bước tiếp theo là so sánh cả hai từ điển và voilá, bạn sẽ đi.

Mặc dù vậy, có một số cảnh báo cho phương pháp này. Một trong số đó là tổng số bản ghi trên mỗi bảng, một bản ghi khác là tần suất cập nhật (nếu nó quá thấp thì không hiệu quả) và một điểm xác định khác là nếu bạn cần truy cập dữ liệu trước đó để sửa đổi/chèn.

Hy vọng điều này sẽ hữu ích.

1

Tại sao bạn không sử dụng dịch vụ Thông báo SQL Server? Tôi nghĩ đó là điều chính xác mà bạn đang tìm kiếm. Đi qua các tài liệu của các dịch vụ thông báo và xem liệu đó có phù hợp với yêu cầu của bạn hay không.

0

Tôi nghĩ có một số ý tưởng tuyệt vời ở đây; từ quan điểm khả năng mở rộng, tôi muốn nói rằng việc kiểm tra bên ngoài séc (ví dụ câu trả lời của Paul Sasik) có lẽ là câu trả lời hay nhất cho đến nay (+1 cho anh ta).

Nếu vì một lý do nào đó, bạn không muốn bên ngoài kiểm tra, thì một tùy chọn khác sẽ là sử dụng HttpCache để lưu trữ người theo dõi và gọi lại.

Trong ngắn hạn, khi bạn đặt bản ghi trong DB mà bạn muốn xem, bạn cũng thêm nó vào bộ đệm (sử dụng phương thức .Add) và đặt SqlCacheDependency trên đó và gọi lại bất kỳ logic nào bạn muốn để gọi khi phụ thuộc được gọi và mục được đẩy ra khỏi bộ nhớ cache.

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