我问这个问题时给出了一个非常翔实的答案:如何对跨多个表的结构具有唯一性约束?
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一起工作。这些事务级别对我来说都是新的,过去我大多在Rails中使用过PostgreSQL,所以还没有深入到SQL中。只是尝试使用CockroachDB推荐的默认CockroachDB事务隔离级别,不确定是否/何时可以/不能使用它,也不确定这种情况。
就我所知,这是关于READ COMMITTED和SERIALIZABLE的。
发布于 2022-08-06 04:50:25
..。CockroachDB ...似乎建议避免使用
READ COMMITTED,而使用SERIALIZABLE。
事实上,根据手册的说法,这不仅仅是一个建议。CockroachDB使用SERIALIZABLE快照隔离,期间:
与大多数数据库相比,CockroachDB总是使用
SERIALIZABLE隔离。
但这对这一解决方案没有任何问题。SERIALIZABLEis只承诺更严格的thanREAD。** (如果有的话),您有更多的回旋余地,同时仍然可以安全地避免并发写负载的争用条件。这是根据SQL标准。但这是没有必要的,因为解决办法应该尽可能快。SERIALIZABLE的问题是它更贵。至少在Postgres是这样的。
在讨论"Postgres vs CockroachDB“的时候。手册:的一个建议
蟑螂实验室建议您使用多列主键或主键列的UUID数据类型。
您的表object_properties可能应该删除添加的代理项id,而使用PRIMARY KEY (source_id, value_id) --也可以替换我建议的CONSTRAINT object_properties_uni UNIQUE (source_id, value_id)。
https://dba.stackexchange.com/questions/315295
复制相似问题