Postgresql

使用 READ COMMITTED 對並發寫入安全的查詢,對 SERIALIZABLE 隔離級別也安全?

  • August 7, 2022

我用一個非常有用的答案問了這個問題:

如何對跨多個表的結構進行唯一性約束?

Erwin Brandstetter 的回答表明了這一點:

WITH ins_string_properties AS (
 INSERT INTO string_properties (source_id, name, value)
 VALUES (gen_random_uuid(), 'slug', 'hello-world')
 ON CONFLICT DO NOTHING  -- to silence unique violation errors
 RETURNING source_id
 )
, ins_objects AS (
 INSERT INTO objects (id, type)
 SELECT o.id, o.type
 FROM   ins_string_properties isp  -- always 0 or 1 rows
 CROSS  JOIN LATERAL (
     VALUES 
       (isp.source_id    , 'baz')
     , (gen_random_uuid(), 'foo')
     , (gen_random_uuid(), 'bar')
     ) o(id, type)
 RETURNING id, type
 )
INSERT INTO object_properties (source_id, name, value_id)
SELECT io1.id, io2.type, io2.id
FROM   ins_objects io1
JOIN   ins_objects io2 ON io1.type = 'foo' AND io2.type = 'bar'
                      OR io1.type = 'bar' AND io2.type = 'baz'
;

我只是在學習 CTE,但答案是:

READ COMMITTED在具有預設事務隔離的並發寫入負載下也是安全的。

我將在 CockroachDB 中使用它,他們似乎建議避免READ COMMITTED使用它SERIALIZABLE

我可以將此查詢與. 一起使用嗎SERIALIZABLE,或者如果不可以,為什麼不 / 必須修改什麼以使其與SERIALIZABLE. 這些事務級別對我來說是新的,過去我主要使用 PostgreSQL 和 Ruby on Rails ORM,所以沒有深入研究 SQL。只是嘗試使用SERIALIZABLECockroachDB 推薦的預設事務隔離級別,並且不確定我是否/何時可以/不能使用它,並且不確定這種情況。

就是我對READ COMMITTEDvs.的了解SERIALIZABLE

… CockroachDB …似乎建議避免READ COMMITTED使用SERIALIZABLE

實際上,根據手冊,這不僅僅是一個建議。CockroachDB 使用SERIALIZABLE快照隔離,期:

與大多數數據庫相比,CockroachDB 總是使用SERIALIZABLE隔離

但這對這個解決方案沒有任何問題。SERIALIZABLE僅比 更嚴格READ COMMITTED如果有的話,您有更多的餘地,同時仍然可以安全地應對並發寫入負載的競爭條件。這是根據 SQL 標準。

但是沒有必要,因為解決方案應該盡可能快。問題SERIALIZABLE是它更貴。至少在 Postgres 中是這樣的。

在討論“Postgres vs CockroachDB”的主題時。手冊中的一個建議

Cockroach Labs 建議您對主鍵列使用多列主鍵或 UUID 數據類型。

您的表object_properties可能應該刪除添加的代理idPRIMARY KEY (source_id, value_id)改用 - 也替換我建議CONSTRAINT object_properties_uni UNIQUE (source_id, value_id)的 .

引用自:https://dba.stackexchange.com/questions/315295