服務一般須要在更新數據的事務中發佈消息。數據庫的更新和消息的發送都必須在一個事務中進行。不然,服務可能會更新是數據庫,而後在消息發送以前崩潰。若是消息不以原子方式執行這兩個操做免責相似的故障可能使系統處於不一致的狀態。數據庫
傳統的解決辦法是在數據庫和消息代理之間使用分佈式事務。然而,分佈式事務對現今的應用而言不是一個很好的選擇。並且,不少新的消息代理,例如Apache Kafka並不支持分佈式事務。併發
所以,應用必須採用不一樣的機制確保消息的可靠發送。分佈式
咱們假設你的應用程序正在使用關係型數據庫。可靠地發佈消息的直接方法是應用事務性發件箱模式。此模式使用數據庫表做爲臨時消息隊列。以下圖所示,發送消息的服務有一個OUTBOX數據庫表。做爲建立、更新和刪除業務對象的數據庫事務的一部分,服務經過將消息插入到OUTBOX表中來發送消息。這樣能夠保證原子性,由於這是本地的ACID事務。代理
OUTBOX表充當臨時消息隊列。MessageRelay是一個讀取OUTBOX表並將消息發佈到消息代理的組件。cdn
你能夠對某些NoSQL數據庫使用相似的方法。做爲record存儲在數據庫中的每一個業務實體都有一個屬性,該屬性是須要發佈的消息列表。當服務更新數據庫中實體時,他會向該列表附加一條消息。這是原子的,由於它是經過單個數據庫操做完成的。可是,挑戰在於有效地找到那些擁有事件併發布事件的業務實體。對象