Postgresql postgres在选择后更新
我想一次完成以下工作:Postgresql postgres在选择后更新,postgresql,select,Postgresql,Select,我想一次完成以下工作: SELECT * FROM jobs WHERE status='PENDING'; UPDATE jobs SET status='RUNNING' WHERE status='PENDING'; 因此,获取所有挂起的作业,然后立即将它们设置为“正在运行” 我不想在两个语句中一个接一个地执行此操作的原因是,作业可以在SELECT之后但在更新之前作为“挂起”添加到作业表中,因此我会将作业设置为正在运行,即使它处于挂起状态时我没有抓取它 还有什么方法可以一次完成吗?因此,
SELECT * FROM jobs WHERE status='PENDING';
UPDATE jobs SET status='RUNNING' WHERE status='PENDING';
因此,获取所有挂起的作业,然后立即将它们设置为“正在运行”
我不想在两个语句中一个接一个地执行此操作的原因是,作业可以在SELECT之后但在更新之前作为“挂起”添加到作业表中,因此我会将作业设置为正在运行,即使它处于挂起状态时我没有抓取它
还有什么方法可以一次完成吗?因此,我希望SELECT的结果和更新能够实时进行
谢谢。一般来说,你应该用一条更新语句来完成。在UPDATE语句运行时,更新通常不会受到可能已更改的行的影响,但是,最好读取事务隔离级别 假设您使用的是Read Committed的默认设置,下面是它的说明: Read Committed是PostgreSQL中的默认隔离级别。当 事务在此隔离级别上运行,SELECT查询只能看到 查询开始前提交的数据 关于更新: 更新、删除、选择用于更新和选择用于共享命令 在搜索目标行方面的行为与SELECT相同:它们 将仅查找在命令start时提交的目标行 时间但是,这样的目标行可能已经更新(或 被另一个并发事务删除或锁定) 建立在这种情况下,可能的更新程序将等待第一次更新 正在更新要提交或回滚的事务(如果仍处于 进展)。如果第一个更新程序回滚,则其效果为 否定,第二个更新程序可以继续更新 原来发现了一排。如果第一个更新程序提交,则第二个更新程序 如果第一个更新程序删除了该行,则将忽略该行,否则将忽略该行 尝试将其操作应用于行的更新版本。这个 命令(WHERE子句)的搜索条件将重新计算为 查看行的更新版本是否仍与搜索匹配 条件如果是,则第二个更新程序继续其操作, 从行的更新版本开始。(如果是SELECT 对于更新,选择共享,这意味着它是更新版本 已锁定并返回给客户端的行的。) 因此,在您的场景中,一次更新就可以了 还请记住,有一个名为
selectforupdate
语句,它将锁定您选择的行。你可以读一下。
您需要使用此功能的场景是在预订系统中。考虑这个例子:
选择
,查看XYZ房间是否可在X日预订UPDATE
query以预订房间但是,在您的场景中,不需要此SELECT FOR UPDATE,因为您在一条语句中完成所有操作,并且没有提前检查任何内容。为什么不使用RETURNING子句并在一条语句中处理这两件事:
begin;
select *
from jobs
where status='pending'
for update
;
update jobs
set status='running'
where status='pending';
commit;
UPDATE jobs
SET status='RUNNING'
WHERE status='PENDING'
RETURNING *
这样,您将通过一个原子操作获得更新更改的所有行。请参阅类似的问题和答案:啊哈!当然,出于某种原因,我甚至没有想到使用RETURNING。谢谢。如果您返回的不仅仅是一个表,而是与其他表以及来自不同表的列的多个联接,该怎么办?我认为这些语句是作为单个单元执行的,第一个语句的输出是更新的输入,但我错了。如果您在第一条语句中添加了一个'AND'子句,而在第二条语句中忽略了它……那么您将面临数据库中的灾难性更新。请在不使用“Commit”关键字的情况下尝试此操作,否则会弄乱数据。对于我的情况,select查询与表和计算上的连接和内部连接非常复杂,我希望更新仅使用这些计算中的值来更新数据库值