无限期锁定行以防止编辑 PostgreSQL 表

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

对于 PostgreSQL 表,我想锁定特定行以防止将来编辑。这是签署审核数据过程的一部分。

从文档和其他线程来看,与锁定有关的所有内容都与在其他数据库进程运行时临时锁定行有关。但是我想阻止用户无限期地修改已审核的数据。

有人有这方面的经验或想法吗?

database postgresql locking
1个回答
0
投票

行级安全策略可以做到这一点:db<>fiddle

演示
create table test (
  id int generated by default as identity primary key,
  payload text,
  is_locked boolean default false);
insert into test values
 (default,'Auditing is due to review this one.',default)
,(default,'We are waiting for legal to sign off on this.',false)
,(default,'This one passed audit and is locked.',true);

create role mc_hammer;
grant usage on schema public to mc_hammer;

alter table test enable row level security;
create policy can_see_this on test for select 
  to mc_hammer using (true);
create policy cant_touch_this_i on test for insert
  to mc_hammer with check (not is_locked);
create policy cant_touch_this_u on test for update
  to mc_hammer using (not is_locked)
          with check (not is_locked);
create policy cant_touch_this_d on test for delete 
  to mc_hammer using (not is_locked);

grant select,insert,update,delete,references,trigger on test to mc_hammer;

现在用户

mc_hammer
可以修改
is_locked=false
所在的行,例如行
1
:

set role mc_hammer;

update test 
  set payload=current_user||' touched this '||now()::text 
  where id=1 
  returning *;
id 有效负载 已锁定
1 mc_hammer 触及了这个 2024-06-14 10:18:06.844776+00 f

但是第

3
行被锁定,因此他们无法
update
delete
它。使用
insert..on conflict do update
merge
进行插入也不起作用。他们也无法
insert
已经锁定的行。它只是不起作用,没有抛出错误:

update test 
  set payload=current_user||' touched this '||now()::text 
  where id=3 
  returning *;
id 有效负载 已锁定
UPDATE 0
set role postgres;
select * from test;
id 有效负载 已锁定
2 我们正在等待法律部门对此的批准。 f
3 此已通过审核并已锁定。 t
1 mc_hammer 触及了这个 2024-06-14 10:18:06.844776+00 f

mc_hammer
尝试同时触摸
1
3
,但它只对
1
有效,因为
3
已被锁定。

您还可以对他们隐藏该列。

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