如何使用 rails 和 postgres 异步更新不同的 json (jsonb) 属性?

How to update different json (jsonb) attributes asynchronously with rails and postgres?

我有一个大的 json 对象存储在 postgres table 列中,模式示例如下:

create_table “document” do |t|
    t.jsonb “data”, default: []
end

目前我正在更新专栏中的 json,如下所示:

# find document in rails then…
doucment.data[‘some_attribute’][2][‘another_attribute’] = 100
doucment.save

但是我多次写入这个 json 属性,有时数据会丢失,因为如果两个调用同时写入它,那么整个对象将被保存或覆盖当前对象的旧数据.

例如,如果有两个不同的保存同时进行,如下

保存 1:

doucment.data[‘some_attribute’][2][‘another_attribute’] = 100
doucment.save

保存 2:

doucment.data[‘some_attribute’][2][‘different_attribute’] = 200
doucment.save

那么其中一个属性数据将丢失,因为另一个将保存它 json 但是旧数据尚未刷新。

使两个调用都正确保存新数据的最佳方法是什么。

是否有任何 json 方法可以只进入并更新一个属性,例如 update_attribute 但对于 jsonb 属性?

Postgresql 有 jsonb_set 方法。您可以使用此方法更新您的模型。

使用此代码,记录在单个查询中更新:

Document.where(id: document.id).update_all(
  "data = jsonb_set(data, '{some_attribute,2,another_attribute}', to_json(#{your_int_value}::int)::jsonb)"
)

Related postgresql document

发生这种情况是因为您异步更新 document,它与 json 属性无关。

这里正确的做法是在修改之前锁定模型,这样它就不会被覆盖,而是一次更新一个步骤。

尝试以下操作:

Document.lock.find_by(...)

ActiveRecord::Locking::Pessimistic