概述
只有生产而没有匹配的提交是偏移的经典来源。事务把数据库写入与事件合成一个单元,稳定的 transactional id 则在重启后隔离旧生产者。
关键步骤
- 配置稳定的 transactional.id,使重启可隔离旧的僵尸生产者。
- 在事务内先写数据库再生产事件。
- 提交事务;任一步出错则中止,使两个效果都不可见。
- 消费者保持 read_committed 隔离级别,避免读到已中止的写入。
验证
- 生产失败会中止数据库写入。
- 已提交事务对 read_committed 消费者可见。
- 重启生产者不会产生重复事件。
- 已中止的写入在下游不可见。
注意事项
- 事务会增加延迟并需要 broker 支持,不适合超高吞吐的尽力而为流。
- 只有当参与存储也加入同一事务协议时,事务才能跨 Kafka 与存储保证原子性。
适用范围
本条目围绕「用原子事务实现 Kafka 生产与提交」给出可复制的步骤、验证方式与常见问题,适合需要按此流程落地的工程团队。执行时请结合自身上下文调整命令与阈值,并在变更前后留存证据,便于后续复核与回滚。
await producer.transaction(async (tx) => {
await db.query('INSERT INTO orders ...');
await tx.send({ topic: 'orders', messages: [event] });
});
// abort on throw leaves neither effect visible