Kafka 事务是什么
事务型生产者把「写多个分区的消息」与「提交消费者位移」绑成一个原子操作,中间任何一步失败都会一起回滚。它解决的是流处理里最常见的读写环问题:从上游读、转换、写下游,如果写入与位移提交分开,崩溃时要么丢数据要么重复。开启事务后,下游消费者只要用 read_committed 隔离级别,就只会看到已经提交的事务,未提交或被中止的记录会被过滤掉。
基本信息
| 适用场景 | 流处理读写环、跨主题原子写 |
|---|---|
| 关键配置 | transactional.id(唯一)、transaction.timeout.ms(默认 60000) |
| 读侧要求 | isolation.level=read_committed |
| 前提条件 | 幂等生产者(开启事务后自动启用) |
| 典型调用 | initTransactions / beginTransaction / commit / abort |
| 超时行为 | 超过事务超时后 broker 会主动中止事务 |
事务使用(Java 片段)
事务使用(Java 片段)
producer.initTransactions();
try {
producer.beginTransaction();
producer.send(record1);
producer.send(record2);
producer.sendOffsetsToTransaction(offsets, consumer.groupMetadata());
producer.commitTransaction();
} catch (Exception e) {
producer.abortTransaction();
}典型使用场景
- 消费转换再写出:读写环上实现精确一次,避免重复投递
- 跨主题原子写:一条业务事件同时写主表与索引主题,要么都成功
- 状态回写:把计算结果与消费进度一起提交,恢复时不重复计算
- 多分区写入:同一批次结果分发到多个分区时保持整体一致
- 对账链路:要求上游与下游消息条数严格一致时使用
关键配置读法
| 配置 | 作用 | 注意 |
|---|---|---|
| transactional.id | 事务标识,决定生产者身份 | 多实例必须各自唯一 |
| transaction.timeout.ms | 事务最大存活时间 | 处理慢的任务需要评估 |
| isolation.level | 读端可见性 | 必须设为 read_committed |
| enable.idempotence | 幂等写入 | 事务会要求开启 |
| max.in.flight.requests | 并发在途请求上限 | 与幂等/事务的约束相关 |
读端不设 read_committed 会读到未提交甚至中止的事务消息;下游跨系统写库时仍要保证幂等。
事务只覆盖 Kafka 内部的一致性:如果事务里还要写外部数据库,需要依靠写入顺序(先写库后提交)或下游幂等来弥补,Kafka 无法替外部系统回滚。