2013-07-23 35 views
14

Hãy tưởng tượng tình hình:Lồng ghép RabbitMQ với các giao dịch cơ sở dữ liệu

var txn = new DatabaseTransaction(); 

var entry = txn.Database.Load<Entry>(id); 
entry.Token = "123"; 
txn.Database.Update(entry); 

PublishRabbitMqMessage(new EntryUpdatedMessage { ID = entry.ID }); 

// A bit more of processing 

txn.Commit(); 

Bây giờ một người tiêu dùng của EntryUpdatedMessage khả năng có thể nhận được tin nhắn này trước giao dịch txn cam kết và do đó sẽ không thể để xem cập nhật. Bây giờ, tôi biết rằng RabbitMQ không hỗ trợ giao dịch của chính nó, nhưng chúng tôi không thể sử dụng chúng bởi vì chúng tôi tạo ra một IModel mới cho mỗi xuất bản và có một mô hình theo chủ đề thực sự cồng kềnh trong kịch bản của chúng tôi (ứng dụng web ASP.NET).

Tôi đã nghĩ đến việc có một danh sách thư được xuất bản khi giao dịch DB được cam kết, nhưng đó là một giải pháp thực sự có mùi.

Cách xử lý đúng cách này là gì?

Trả lời

28

RabbitMQ khuyến khích bạn sử dụng xác nhận của nhà xuất bản thay vì giao dịch. Giao dịch không hoạt động tốt.

Trong mọi trường hợp, giao dịch thường không hoạt động tốt với kiến ​​trúc hướng dịch vụ. Tốt hơn là nên áp dụng cách tiếp cận 'cuối cùng nhất quán', nơi mà sự thất bại có thể được thử lại vào một ngày sau đó và các thông điệp nhàn rỗi trùng lặp được bỏ qua.

Trong ví dụ của bạn, tôi sẽ thực hiện cập nhật cơ sở dữ liệu và cam kết trước khi xuất bản thư. Khi nhà xuất bản xác nhận trả về, tôi sẽ cập nhật một trường trong bản ghi cơ sở dữ liệu để cho biết rằng thư đã được gửi. Sau đó bạn có thể có một quá trình quét dọn đi kèm sau, kiểm tra các thư chưa gửi và gửi chúng trên đường đi. Nếu thông báo đã được thông qua, nhưng vì lý do nào đó xác nhận, hoặc viết cơ sở dữ liệu tiếp theo thất bại, bạn sẽ nhận được một thông báo trùng lặp. Nhưng điều đó sẽ không thành vấn đề, bởi vì bạn đã thiết kế các thông điệp của bạn là không đáng tin cậy.

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