使用 READ COMMITTED 對並發寫入安全的查詢,對 SERIALIZABLE 隔離級別也安全?
我用一個非常有用的答案問了這個問題:
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。只是嘗試使用SERIALIZABLE
CockroachDB 推薦的預設事務隔離級別,並且不確定我是否/何時可以/不能使用它,並且不確定這種情況。這就是我對
READ COMMITTED
vs.的了解SERIALIZABLE
。
… CockroachDB …似乎建議避免
READ COMMITTED
使用SERIALIZABLE
。實際上,根據手冊,這不僅僅是一個建議。CockroachDB 使用
SERIALIZABLE
快照隔離,期:與大多數數據庫相比,CockroachDB 總是使用
SERIALIZABLE
隔離但這對這個解決方案沒有任何問題。
SERIALIZABLE
僅比 更嚴格READ COMMITTED
。如果有的話,您有更多的餘地,同時仍然可以安全地應對並發寫入負載的競爭條件。這是根據 SQL 標準。但是沒有必要,因為解決方案應該盡可能快。問題
SERIALIZABLE
是它更貴。至少在 Postgres 中是這樣的。在討論“Postgres vs CockroachDB”的主題時。手冊中的一個建議:
Cockroach Labs 建議您對主鍵列使用多列主鍵或 UUID 數據類型。
您的表
object_properties
可能應該刪除添加的代理id
並PRIMARY KEY (source_id, value_id)
改用 - 也替換我建議CONSTRAINT object_properties_uni UNIQUE (source_id, value_id)
的 .