【发布时间】:2021-07-25 02:25:47
【问题描述】:
我需要运行一些数据库操作并为 Kafka 主题生成事件。但是,事件内容取决于从数据库中读取的内容和事件的顺序。考虑这样的操作:
- 开启交易
- 从表中读取
- 更新表
- 再次从表中读取
- 向主题发送事件
- 提交交易
现在我知道可序列化的隔离级别保证数据库中的数据是一致的。同时运行此操作的两个服务实例总是会读取有效数据,就好像事务是按顺序运行的一样。但是向 Kafka 主题发送事件也是如此吗?
这种情况是否可能:
- 实例 A 运行、读取数据并准备要发出的事件
- 实例 B 运行,读取数据,就像它在 A 之后运行一样,并准备要发出的事件
- 实例 B 发出事件
- 实例 A 发出事件
在上述场景中,事件的顺序是错误的。如果实例 A 在实例 B 引入更改之前根据数据准备了事件,则应首先发出其事件。
我认为这个问题归结为事务 B 何时会失败的问题?它是否在第 4 点失败 - 因为数据已被另一个事务更改?还是在提交时失败 - 在 Kafka 事件已经产生之后?
或者有没有可能根本没有失败?就像在这种情况下:
- A 读取
- 更新
- A 再次读取
- B 读取(A 已更新数据)
- B 更新
- B 再次读取 -- 没有冲突,因为 B 在 A 之后运行所有 DB 操作
- B 发出事件
- A 发出事件
没有抛出错误,但事件顺序错误
最好的解决方案应该是 DB-angnostic,但如果重要的话,我会使用 PostgreSQL 10.16
【问题讨论】:
标签: sql database postgresql transactions isolation-level