一 背景
写DB后发消息,如何保证两者的一致性性?
二 方案
2.1 事务(错误方案)
写DB和发消息通过事务保证,发消息失败后,数据库进行回滚。
这种情况下,如果发消息超时、但是发送成功了,会导致数据库进行回滚、但是消息发送成功了。
2.2 引入binlog机制
核心思想是将分布式事务简化为本地事务+重试+下游调用方幂等。
步骤
1、DB写入,写入消息记录表。
2、监听消息记录表的binlog,发送数据。
3、如果数据发送成功,更新消息记录表。
4、定时拉取消息记录表中的数据,发送消息。
消息记录表
CREATE TABLE message_box (
id bigint auto_increment primary key comment '主键id',
topic_name VARCHAR(1000) NOT NULL comment '消息最终发送topic',
topic_partition_key bigint comment '消息最终topic发送时,对于的paritionkey',
payload json NOT NULL comment '消息内容',
ext_data json comment '扩展信息',
retry_count int(10) DEFAULT 0 comment '重试次数',
published SMALLINT DEFAULT 0 comment '是否已发送',
gmt_create timestamp default CURRENT_TIMESTAMP not null comment '创建时间',
gmt_modified timestamp default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新'
) comment '消息表' charset = utf8mb4;
三 总结
最终采用的方案是最终一致性性,最终一致性的设计理念就是通过
数据状态表+冥等+本地事务,将分布式事务进行拆解。
如果采用强一致性质,则需要进行两阶段提交,保障各个子事务的一致性。