我有一个Sidekiq
工作者,它进行API调用,解析返回的json并创建ActiveRecord
个对象(产品)。由于产品属于某个品牌,而产品json也包含该品牌的数据,因此工作人员在将产品实际保存到数据库之前会执行以下操作:
我已经像这样实现了这个:
def brand_id(brand_json)
Brand.where(api_id: brand_json[:api_id]).pluck(:id).first.presence ||
Brand.create!(name: brand_json[:name], api_id: brand_json[:api_id]).id
end
之后,工作人员创建产品,并将brand_id设置为已获取的ID。
现在我在考虑以下情况:
现在工人2会发生什么?我的假设 - 它试图创建品牌,但是在数据库级别出现错误,因为已经存在具有相同api_id的记录? (可能会出现ActiveRecord::RecordNotUnique
错误?)
此外,如何在Sidekiq
和ActiveRecord
的上下文中处理此案例和此类错误?我应该以某种方式在品牌表上实施表格范围的锁定以防止此类事情发生吗?如果是 - 我将无法同时创建产品,因为在任何给定时间只有一名工人可以访问品牌表,这是创建产品所必需的。
或许我应该将我的brand_id(brand_json)
方法包装在事务中,如下所示:
def brand_id(brand_json)
ActiveRecord::Base.transaction do
Brand.where(api_id: brand_json[:api_id]).pluck(:id).first.presence ||
Brand.create!(name: brand_json[:name], api_id: brand_json[:api_id]).id
end
end
请建议。
答案 0 :(得分:1)