外盒流程(MongoDB 事务示意)
外盒流程(MongoDB 事务示意)
// 副本集/分片集群事务内:业务写入 + 外盒事件
const session = db.getMongo().startSession();
session.startTransaction();
try {
session.getDatabase("app").orders.insertOne(
{ _id: 1001, status: "paid", amount: 128 },
{ session }
);
session.getDatabase("app").outbox.insertOne(
{ eventId: UUID(), type: "order.paid", payload: { orderId: 1001 }, status: "pending" },
{ session }
);
session.commitTransaction();
} catch (e) {
session.abortTransaction();
throw e;
}
// 中继:轮询 pending 并投递,成功后标记 sent(至少一次投递)| 中继实现 | 轮询 findOneAndUpdate 抢占,或直接消费 outbox 集合的 change stream |
|---|---|
| 投递语义 | 至少一次;消费端按 eventId 幂等去重 |
| 有 CDC 时 | 由 CDC 直接消费变更日志可以省去外盒,但事件格式与过滤条件要在日志层设计 |
外盒事件建议带唯一 eventId 与业务主键:消费端用唯一索引去重,重复投递不会产生重复副作用。