【发布时间】:2016-06-14 03:08:39
【问题描述】:
我有多个线程将事件写入 MySQL 表 events。
该表有一个配置为auto_increment 的tracking_no 列,用于强制对事件进行排序。
不同的读者从 events 消费,他们定期轮询表以获取新事件,并保留上次消费事件的值以在每次轮询时获取所有新事件。
事实证明,当前的实现可能会丢失一些事件。
这是正在发生的事情:
-
Thread-1开始一个“插入”事务,它从 auto_increment 列 (1) 中获取下一个值,但需要一段时间才能完成 -
Thread-2开始一个“插入”事务,它获取下一个 auto_incremente 值 (2) 并在Thread-1之前完成写入。 -
Reader轮询并询问所有 tracking_number 大于 0 的事件;它得到事件 2,因为Thread-1仍然落后。 事件被消耗,Reader将其跟踪状态更新为 2。 -
Thread-1完成插入,事件1出现在表格中。 -
Reader再次轮询 2 之后的所有事件,当插入事件 1 时,它将永远不会被再次拾取。
这似乎可以通过更改auto_increment 策略来解决,以锁定整个表直到事务完成,但如果可能我们会避免它。
【问题讨论】:
-
我会添加一个时间戳列,以反映事件的创建时间(即使它最后一次更新),并且消费者会在特定时间后查询插入(甚至可能更新)的事件。这将使您能够在没有表锁定的情况下使用 auto_increment。另一种解决方案是减少交易打开的时间以避免此类问题。
-
时间戳值如何生成?
标签: mysql multithreading event-sourcing