Postgresql 锁定行,稍后释放

Postgresql 锁定行,稍后释放,postgresql,transactions,Postgresql,Transactions,我试图理解如何锁定一行,并且只在以后释放该锁 我有一张这样的桌子: create table testTable (Name varchar(100)); begin transaction; select * from testTable where name = 'Bob' for update; 一些测试数据 insert into testTable (name) select 'Bob'; insert into testTable (name) select 'John'; in

我试图理解如何锁定一行,并且只在以后释放该锁

我有一张这样的桌子:

create table testTable (Name varchar(100));
begin transaction;
select * from testTable where name = 'Bob' for update;
一些测试数据

insert into testTable (name) select 'Bob';
insert into testTable (name) select 'John';
insert into testTable (name) select 'Steve';
现在,我想选择其中一行,并防止其他查询看到这一行。我是这样做到的:

create table testTable (Name varchar(100));
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';
但博士后并不支持这一点。我发现了“preparetransaction”,但这似乎是一条梨形的路径,我不想走下去,尤其是当这些事务似乎在重启后仍然存在时


对于特定的事务,是否还有提交/回滚的引用?

在数据库会话中只能有一个事务,因此这个问题本身是没有意义的

但我假设您并不是真的想要运行事务,而是想要在一段时间内阻止对某一行的访问

为此目的使用常规数据库锁通常不是一个好主意(例外是咨询锁,它正好用于此目的,但不绑定到表行)。问题是,长时间的数据库事务使autovacuum无法完成其工作

我建议您在表中添加一个
status
列,并更改状态,而不是锁定行。这将以一种更自然的方式达到同样的目的,让你的问题消失


如果您担心由于应用程序逻辑问题,
状态
标志可能无法清除,请将其替换为列中的可见(类型为带有时区的时间戳),该列最初包含-无限。不要锁定行,而是将值设置为
current\u timestamp+INTERVAL'5 minutes'
。仅选择从可见的
行。这样,“锁”将在5分钟后自动过期。

我最初也考虑过使用状态栏,这是执行此类操作的标准方式。问题是,这是这个解决方案的第二次迭代,我们在上一个版本中被烧掉了,因为行会“卡住”(流程在更改回状态之前死亡),所以我们试图避开它。我得多看看四周。我用一个想法扩展了答案。我很高兴看到我们提出了相同的想法!我在一次会议上也提出了这个建议,在这一行有一些“过期”,但这个想法并不适合团队领导。那么,团队领导必须准确地定义他们想要什么,如果你需要的话,你可以在这里详细地问这个问题。