【问题标题】:Jruby on Rails simultaneous save on the same tableJruby on Rails 同时保存在同一张表上
【发布时间】:2015-06-05 03:18:27
【问题描述】:

如果两个或多个用户使用 Jruby 同时单击保存,我如何将数据保存在同一张表上? 这是我已经尝试过的代码

Sequence.transaction do
sq = Sequence.find_by_sequence_key('bus20158001', :lock => true)
sq.values = sq.values + 1
sq.save
end

以上代码由于某些原因无法正常工作 序列是我的模型,它的字段是 (id, sequence_key, values, created_at, updated_at)

【问题讨论】:

  • 请不要在标题中对我们大喊大叫。
  • 当您在 Ruby 中增加 values 时,您想避免竞争条件吗?
  • 比如我的序列值是40,然后两个用户同时保存,user1的值变成了41,然后user2的值还是41,应该是42。

标签: ruby-on-rails ruby concurrency jruby simultaneous


【解决方案1】:

“简单”的答案是您需要确保检索、增量和保存是互斥的:

Sequence.exclusively do
  Sequence.transaction do
    sq = Sequence.find_by_sequence_key('bus20158001', :lock => true)
    sq.values = sq.values + 1
    sq.save
  end
end

您需要一个“全局”共享互斥锁,例如:

class Sequence
  @@mutex = Mutex.new
  def exclusively; @@mutex.synchronize { yield } end
end

请注意,通常这可能是争用的来源(尤其是如果 find_by 需要一些应有的时间总是查看数据库)...

...因此,另一个答案是在数据库级别使值成为类似“原子”序列的计数器列(例如,您可以根据表中的当前最大值在每次保存时使用触发器更新它)。

【讨论】:

    猜你喜欢
    • 2011-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多