Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails 4中的潜在竞争条件_Ruby On Rails_Activerecord_Race Condition - Fatal编程技术网

Ruby on rails Rails 4中的潜在竞争条件

Ruby on rails Rails 4中的潜在竞争条件,ruby-on-rails,activerecord,race-condition,Ruby On Rails,Activerecord,Race Condition,给定的用户和事务模型: class User < ActiveRecord::Base has_many :transactions end class Transaction < ActiveRecord::Base belongs_to :user end 首先,我有一个竞争条件,只使用@data.user更新用户平衡,有时新请求在前一个请求之前完成,因此我们丢失了一些数据。相反,我开始请求锁定该用户 下一个竞争条件是计算总交易量,我现在看到的是,我们将有另一

给定的用户和事务模型:

class User < ActiveRecord::Base
  has_many     :transactions
end

class Transaction < ActiveRecord::Base
  belongs_to :user
end
首先,我有一个竞争条件,只使用
@data.user
更新用户平衡,有时新请求在前一个请求之前完成,因此我们丢失了一些数据。相反,我开始请求锁定该用户

下一个竞争条件是计算总交易量,我现在看到的是,我们将有另一个带有inform_user的RC

所以问题是我做错了吗?用以下方法重写inform_用户的更新平衡是否是一种好方法:

    inform_user.with_lock do
      inform_user.balance     = inform_user.aff_balance.to_f + @amount.to_f
    end

还有一个问题,使用嵌套锁是否是一种好方法,例如,当我需要在更新父关系模型的同时更新关系模型时?

您需要直接根据数据库拥有的内容(而不是Rails模型当前拥有的内容)通过添加/减去来更新数据库。查看
更新\u计数器


谢谢您的建议,使用update_计数器来更新用户余额而不是Model.transaction可以吗?因为Rails API建议使用简单的事务,而不适用于复杂的模型。当我在模型上创建或更新关联时,锁定模型的最佳方法是什么?
    inform_user.with_lock do
      inform_user.balance     = inform_user.aff_balance.to_f + @amount.to_f
    end
# For the Post with id of 5, decrement the comment_count by 1, and
# increment the action_count by 1
Post.update_counters 5, comment_count: -1, action_count: 1
# Executes the following SQL:
# UPDATE posts
#    SET comment_count = COALESCE(comment_count, 0) - 1,
#        action_count = COALESCE(action_count, 0) + 1
#  WHERE id = 5