希望在數據庫有新數據行插入時,客戶端無需發起查詢即可感知,類似 Socket 的推送機制。
| 方案 | 原理 | 優點 | 缺點 |
|---|---|---|---|
| 數據庫觸發器 + 擴展存儲過程 | 在 INSERT 觸發器中調用擴展存儲過程(如 xp_cmdshell 或 CLR)發送 Socket 通知 |
無需修改應用代碼 | 強耦合數據庫,擴展存儲過程安全風險高,性能差 |
| 中間件訂閱/發布 | 應用層寫入數據後,同時發布消息到 RabbitMQ/Kafka/Redis PubSub,客戶端訂閱 | 解耦、高性能、支持多客戶端 | 需引入消息中間件,架構複雜度上升 |
| 數據庫 CDC (Change Data Capture) | 利用 SQL Server CDC/Oracle GoldenGate 捕獲變更,由同步服務推送 | 非侵入式,捕獲完整變更 | 配置較繁瑣,延遲取決於捕獲頻率 |
| 應用層雙寫 | 業務代碼寫入 DB 成功後,主動調用 Socket/WebSocket 推送給客戶端 | 邏輯清晰,可控性強 | 需修改所有寫入入口,事務一致性需自行保證 |
對於 Win32 客戶端場景,建議採用 應用層雙寫 + WebSocket:
WebSocket (如 websocketpp、Boost.Beast) 維持長連接。// 服務端廣播
void notify_clients(const json::value& msg) {
for (auto& ws : connected_clients) {
ws.send(msg.serialize()).wait();
}
}
// 業務寫入後調用
void insert_order(Order order) {
db.execute("INSERT INTO orders ...");
notify_clients(json::value::object({{U("type"), json::value::string(U("new_order"))},
{U("data"), order.to_json()}}));
}
結論: 數據庫本身不支持主動推送,切勿嘗試在觸發器中實現網絡通訊。應在應用層實現事件驅動架構,才是穩健可擴展的方案。