在多线程环境中以原子方式更新DB字段的计数

时间:2015-12-02 19:19:45

标签: ruby-on-rails postgresql activerecord

注意 - 此问题扩展了对另一个问题here的回答。

我将文件导入到我的数据库中,将其分成较小的组并生成后台作业以导入每个块(100行)。

我想要一种方法来跟踪到目前为止已经导入了多少块的进度,所以我已经计划在每个作业上将DB字段递增1,所以我知道到目前为止已经处理了多少。

这可能会导致两个并行作业同时将DB字段递增1并相互覆盖。

避免这种情况并确保原子并行操作的最佳方法是什么?上面的链接帖子建议使用Redis,这是一种很好的方法。出于这个问题的目的,我很好奇是否有另一种方法可以使用持久存储。

我在Rails中使用ActiveRecord和Postgres作为我的数据库。

谢谢!

2 个答案:

答案 0 :(得分:2)

我建议不要将DB字段递增1,而是为每个具有作业ID的作业创建一个DB记录。有两个好处:

  1. 您可以计算记录数,让您知道处理了多少记录而不必担心并行操作。
  2. 您还可以在每个作业记录中添加一些必要的日志,并在导入时任何作业失败时轻松调试。

答案 1 :(得分:0)

我建议你使用postgresql序列。

请参阅CREATE SEQUENCESequence Manipulation。 特别是nextval()

  

将序列对象前进到其下一个值并返回该值。这是以原子方式完成的:即使多个会话同时执行nextval,每个会安全地接收一个不同的序列值