【问题标题】:Race condition when updating a field in Sidekiq在 Sidekiq 中更新字段时的竞争条件
【发布时间】:2014-07-11 20:23:59
【问题描述】:

我在 Sidekiq 中有两个线程并发,有一次我在我的一个模型中调用了以下方法:

def update_pending
  update(pending_stats: self.pending_stats + 1)
end

我希望当两个作业都完成时,pending_stats 属性是两个,但它只是一个,即使两个线程都调用该方法。

如何确保两个线程实际上更新为正确的值?

【问题讨论】:

    标签: ruby-on-rails ruby thread-safety race-condition sidekiq


    【解决方案1】:

    尝试使用increment_counter,这是一个原子操作。

    def update_pending increment_counter(:pending_status, 1) 结尾

    这将执行以下 SQL:

    更新 ... SET pending_status = COALESCE(pending_status, 0) + 1 在哪里 ...

    【讨论】:

    • 我看到这样做的时候需要重新加载对象?否则,即使在数据库中执行了更改,对象也会保留旧值。这是为什么呢?
    • 是的,如果我们关心更新后数据库中的新pending_status,则需要重新加载对象。由于它是一个类方法,它不知道要重新加载的对象。
    • 我可以做到,因为我有对象。但是,重新加载对象有什么影响?
    猜你喜欢
    • 2015-03-19
    • 2023-03-17
    • 2017-02-11
    • 1970-01-01
    • 2020-08-01
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多