我试图了解如何锁定行,并且仅在以后释放该锁定。
我有一张这样的桌子:
create table testTable (Name varchar(100));
一些测试数据
insert into testTable (name) select 'Bob';
insert into testTable (name) select 'John';
insert into testTable (name) select 'Steve';
现在,我想选择这些行之一,并防止其他查询看到此行。我这样实现:
begin transaction;
select * from testTable where name = 'Bob' for update;
在另一个窗口中,我这样做:
select * from testTable for update skip locked;
[很好,我在该结果集中看不到“鲍勃”。现在,我想对主要的检索行(Bob)进行处理,完成我的工作后,我想再次释放该行。简单的答案是:提交交易
但是,我在同一个连接上运行多个事务,所以我不能只是在整个节目中开始并提交事务。理想情况下,我希望进行“命名”交易,例如:
begin transaction 'myTransaction';
select * from testTable where name = 'Bob' for update;
//do stuff with the data, outside sql then later call ...
commit transaction 'myTransaction';
但是postgres不支持。我已经找到了“准备交易”,但这似乎是一条梨形的路,我不想走下去,尤其是因为这些交易甚至在重启后仍会持续。
无论如何,我是否可以参考特定事务的提交/回退?
您在数据库会话中只能有一个事务,因此这样的问题就没有意义了。
但是我假设您并不是真的要运行事务,而是想暂时阻止对某一行的访问。
通常,出于这种目的使用常规数据库锁不是一个好主意(例外是咨询锁,它恰好用于该目的,但不与表行绑定)。问题是长时间的数据库事务使自动清理工作无法进行。
我建议您在表中添加status
列并更改状态,而不是锁定行。这将以更自然的方式实现相同的目的,并解决您的问题。
[如果担心由于应用程序逻辑问题而无法清除status
标志,请用最初包含visible_from
的timestamp with time zone
类型的-infinity
列替换它。将值设置为current_timestamp + INTERVAL '5 minutes'
,而不是锁定行。仅选择满足WHERE visible_from < current_timestamp
的行。这样,“锁定”将在5分钟后自动失效。