在不使用两个单独的查询的情况下执行特定语句之前是否有任何安全的方法来获取咨询锁?例如,我假设如果我执行以下操作,则不能保证在插入之前会获得锁:
WITH x AS (SELECT pg_advisory_lock(1,2)) INSERT ...
但是有没有类似的方法可以达到预期的效果?
在不使用两个单独的查询的情况下执行特定语句之前是否有任何安全的方法来获取咨询锁?例如,我假设如果我执行以下操作,则不能保证在插入之前会获得锁:
WITH x AS (SELECT pg_advisory_lock(1,2)) INSERT ...
但是有没有类似的方法可以达到预期的效果?
您还没有真正告诉我们足够的用例来确定,但一般来说,要在 PostgreSQL 中使用显式锁,需要在事务获取其快照之前获取它们。建议锁可以在你开始事务之前获取,大多数事务范围的锁应该在你开始事务之后立即获取;在需要交易ID的任何事情之前。
如果您在分配事务 ID 和设置快照之前确实不需要获取锁,并且发出一条语句来获取锁并执行插入对您很重要,请创建一个同时执行这两种操作的函数。
我很确定 SQL 标准要求实现表现得好像他们所做的第一件事就是有效地实现 WITH 子句中的公共表表达式。PostgreSQL 符合这个要求。
公用表表达式(大部分)表现为命名对象。多个 CTE 按照声明的顺序实现。按名称向后引用按预期工作,按名称向前引用会引发错误。
所以我很确定,在一般情况下,CTE 必须在 INSERT 语句运行之前实现。但是在您的情况下,使用 PostgreSQL,我不确定,这就是原因。
PostgreSQL 的[公用表表达式] 的实现只评估 WITH 查询的行数,该行数与父查询实际获取的行数一样多。
我不确定 INSERT 语句是否在这个意义上获取一行。