在 Postgres 过程执行时锁定表上的写入操作

问题描述 投票:0回答:1

我在 Postgres 中创建了一个过程,该过程将创建一个包含另外三个表(带有 JOINS 的 SELECT)内容的表。然后生成的表将被更改,添加之前不存在的两列,最后在同一过程中我创建了 3 个触发器,这些触发器将应用于这三个表,因此每当在其中任何一个表上发生新的写入时,都会记录相同的实体在新表中

我知道该过程本身是原子的,并且在其自身范围内是事务性的,但该过程无法了解有关这三个表的任何信息。恐怕在创建新表和创建触发器之间的时间里,可能会发生对现有表的一些写入,从而使新表不同步,而新表不会注册这些写入。那不可能发生。

我的表创建/触发器创建过程如下所示:

CREATE OR REPLACE PROCEDURE myschema.table_creation()
LANGUAGE plpgsql
AS $procedure$
begin
create table newtable as
SELECT * FROM myschema.session a NATURAL JOIN (SELECT * FROM myschema.message b NATURAL left JOIN myschema.data) as d;
ALTER TABLE myschema.newtable ADD created_at timestamp;
ALTER TABLE myschema.newtable ADD source text;
CREATE TRIGGER mytrigger
after INSERT
ON myschema.session
FOR EACH ROW
EXECUTE PROCEDURE myschema.trigger_proc();
CREATE TRIGGER mytrigger
after INSERT
ON myschema.messages
FOR EACH ROW
EXECUTE PROCEDURE myschema.trigger_proc();
CREATE TRIGGER mytrigger
after INSERT
ON myschema.data
FOR EACH ROW
EXECUTE PROCEDURE myschema.trigger_proc();
end;
$procedure$
; 

如何锁定现有表中的写入以推迟它们,直到整个 table_creation 过程完成?否则,我会遇到竞争条件,并且一些实体将在新表中丢失。我认为我的程序在当前状态下没有任何针对写入的保护

database postgresql locking plpgsql psql
1个回答
0
投票

为了绝对确定,请在三个源表上获取排他锁。我建议使用

SHARE
锁。 说明书:

[...] 此模式可保护表免受并发数据更改的影响。

BEGIN;

LOCK TABLE myschema.session, myschema.message, myschema.data IN SHARE MODE;  -- !!!

CREATE TABLE newtable AS
SELECT *
FROM   myschema.session a
NATURAL JOIN (
   SELECT *
   FROM   myschema.message b
   NATURAL LEFT JOIN myschema.data
   ) d;

ALTER TABLE myschema.newtable  -- single command (faster)
  ADD created_at timestamp
, ADD source text;

CREATE TRIGGER mytrigger
AFTER INSERT ON myschema.session
FOR EACH ROW EXECUTE FUNCTION myschema.trigger_proc(); -- it's really a function

CREATE TRIGGER mytrigger
AFTER INSERT ON myschema.messages
FOR EACH ROW EXECUTE FUNCTION myschema.trigger_proc();

CREATE TRIGGER mytrigger
AFTER INSERT ON myschema.data
FOR EACH ROW EXECUTE FUNCTION myschema.trigger_proc();

COMMIT;

由于这显然是一次性操作,没有特定于 PL/pgSQL 的操作,因此我不会创建过程。一个简单的交易就可以完成这项工作。

© www.soinside.com 2019 - 2024. All rights reserved.