我试图在一个复杂的实体上实现悲观锁定,但是Postgres不支持SELECT FOR UPDATE和OUTER JOIN空字段。是否有变通办法?
范例:
create table A(
id serial primary key,
name character varying(20) not null
);
create table B(
id serial primary key,
a_id int references a(id) on delete cascade not null,
name character varying(20) not null
);
create table C(
id serial primary key,
b_id int references b(id) on delete cascade not null,
name character varying(20) not null
);
// Query:
SELECT *
FROM A
LEFT JOIN B ON A.id = B.a_id
LEFT JOIN C ON B.id = C.b_id
WHERE A.id = 5;
我需要一种方法来执行这样的查询,锁定表a,b和c中的行进行更新。此外,我需要锁定插入表B和C中的行,即选定行上的引用。
SELECT *
FROM A
LEFT JOIN B ON A.id = B.a_id
LEFT JOIN C ON B.id = C.b_id
WHERE A.id = 5
FOR UPDATE; <<---- DOES NOT WORK IN POSTGRES
现在我明白了,唯一的方法是做3个SELECT语句,从表A、B和C中选择行进行更新,并在应用程序端连接它们,但这种方式似乎比在数据库端连接慢。
有没有办法在数据库中执行JOIN,锁定所有选定的行?
1条答案
按热度按时间t40tm48m1#
在PostgreSQL中,查询不可能强制执行悲观锁定,因为PostgreSQL不接受任何表提示,也不接受查询的任何部分中的任何提示,如Micosoft SQL Server,Oracle数据库或任何其他RDBMS(您必须通过购买企业版来支付)。
您唯一能做的就是编写一个SQL脚本或PF“函数”作为一个过程,在该过程中,您将显式地锁定显式事务中的表。
例如:
这不是PG唯一不能做的事情,看看这篇论文:“PostgreSQL vs. SQL Server (MSSQL) – part 3 – Very Extremely Detailed Comparison“