update语句的PostgreSQL

update语句的PostgreSQL,postgresql,transactions,Postgresql,Transactions,PostgreSQL已读取提交的隔离级别。现在我有一个事务,它由一个DELETE语句组成,这个DELETE语句有一个子查询,它由一个SELECT语句组成,用于选择要删除的行 我必须在select语句中使用FOR UPDATE才能与其他事务不冲突,这是真的吗 我的想法如下:首先从表中读取相应的行,然后在第二步中删除这些行,这样另一个事务可能会干扰 还有一个简单的从myTable中删除id=4语句呢?我是否也必须使用更新 我必须在select语句中使用FOR UPDATE来 是否与其他事务没有冲突

PostgreSQL已读取提交的隔离级别。现在我有一个事务,它由一个DELETE语句组成,这个DELETE语句有一个子查询,它由一个SELECT语句组成,用于选择要删除的行

我必须在select语句中使用FOR UPDATE才能与其他事务不冲突,这是真的吗

我的想法如下:首先从表中读取相应的行,然后在第二步中删除这些行,这样另一个事务可能会干扰

还有一个简单的从myTable中删除id=4语句呢?我是否也必须使用更新

我必须在select语句中使用FOR UPDATE来 是否与其他事务没有冲突

“与其他交易无冲突”对您意味着什么?您可以通过打开两个终端并在每个终端中执行语句来测试这一点。正确交错后,DELETE语句将使“other transaction”(隔离级别设置为
READ COMMITTED
)等待提交或回滚

                                                 sandbox=# set transaction isolation level read committed;
                                                 SET

sandbox=# select * from customer;
 date_of_birth 
---------------
 1996-09-29
 1996-09-28
(2 rows)

sandbox=# begin transaction;
BEGIN
sandbox=# delete from customer
sandbox-# where date_of_birth = '1996-09-28';
DELETE 1
                                                 sandbox=# update customer
                                                 sandbox-# set date_of_birth = '1900-01-01'
                                                 sandbox-# where date_of_birth = '1996-09-28';
                                                 (Execution pauses here, waiting for transaction in other terminal.)
sandbox=# commit;
COMMIT
sandbox=# 
                                                 UPDATE 0
                                                 sandbox=# 
有关文档,请参见下文

还有一个简单的从myTable中删除id=4语句呢?做 我也要用它来更新吗

没有像
DELETE这样的语句。用于更新


在阅读有关数据库更新的信息时,您需要对上下文敏感。更新可能意味着对数据库的任何更改;它可以包括插入、删除和更新行。在下面引用的文档中,“为更新而锁定”明确地指的是更新和删除语句等

FOR UPDATE使SELECT语句检索到的行 已锁定,好像要更新。这可以防止它们被修改或删除 被其他事务删除,直到当前事务结束。那个 是,尝试更新、删除、选择更新的其他事务, 选择“无密钥更新”,选择“共享”,或选择“密钥共享” 这些行将被阻止,直到当前事务结束。为 更新锁定模式也可以通过行上的任何删除以及 修改某些列上的值的更新。目前, 更新案例中考虑的列集是具有 可以在外键中使用的唯一索引(如此部分 不考虑索引和表达式索引),但这可能 未来的变化。此外,如果需要更新,请删除或选择进行更新 来自另一个事务的已锁定选定行, 选择更新将等待其他事务完成,并且 然后将锁定并返回更新后的行(如果该行为空,则不返回行) 删除)

我必须在select语句中使用FOR UPDATE来 是否与其他事务没有冲突

“与其他交易无冲突”对您意味着什么?您可以通过打开两个终端并在每个终端中执行语句来测试这一点。正确交错后,DELETE语句将使“other transaction”(隔离级别设置为
READ COMMITTED
)等待提交或回滚

                                                 sandbox=# set transaction isolation level read committed;
                                                 SET

sandbox=# select * from customer;
 date_of_birth 
---------------
 1996-09-29
 1996-09-28
(2 rows)

sandbox=# begin transaction;
BEGIN
sandbox=# delete from customer
sandbox-# where date_of_birth = '1996-09-28';
DELETE 1
                                                 sandbox=# update customer
                                                 sandbox-# set date_of_birth = '1900-01-01'
                                                 sandbox-# where date_of_birth = '1996-09-28';
                                                 (Execution pauses here, waiting for transaction in other terminal.)
sandbox=# commit;
COMMIT
sandbox=# 
                                                 UPDATE 0
                                                 sandbox=# 
有关文档,请参见下文

还有一个简单的从myTable中删除id=4语句呢?做 我也要用它来更新吗

没有像
DELETE这样的语句。用于更新


在阅读有关数据库更新的信息时,您需要对上下文敏感。更新可能意味着对数据库的任何更改;它可以包括插入、删除和更新行。在下面引用的文档中,“为更新而锁定”明确地指的是更新和删除语句等

FOR UPDATE使SELECT语句检索到的行 已锁定,好像要更新。这可以防止它们被修改或删除 被其他事务删除,直到当前事务结束。那个 是,尝试更新、删除、选择更新的其他事务, 选择“无密钥更新”,选择“共享”,或选择“密钥共享” 这些行将被阻止,直到当前事务结束。为 更新锁定模式也可以通过行上的任何删除以及 修改某些列上的值的更新。目前, 更新案例中考虑的列集是具有 可以在外键中使用的唯一索引(如此部分 不考虑索引和表达式索引),但这可能 未来的变化。此外,如果需要更新,请删除或选择进行更新 来自另一个事务的已锁定选定行, 选择更新将等待其他事务完成,并且 然后将锁定并返回更新后的行(如果该行为空,则不返回行) 删除)


简短版本:子选择中更新的
是不必要的,因为
删除
实现已经执行了必要的锁定。这是多余的

理想情况下,您应该阅读和消化以了解SQL引擎如何处理并发性问题

特别是对于您提到的案例,我认为以下两个摘录最为相关:

更新、删除、选择用于更新和选择用于共享命令 在搜索目标行方面的行为与SELECT相同:它们 将仅查找在命令start时提交的目标行 时间

但是,这样的目标行可能已经更新(或 被另一个并发事务删除或锁定) 建立在这种情况下,可能的更新程序将等待第一次更新 正在更新要提交或回滚的事务(如果仍处于 进展)

因此,两个并发删除中的一个将被置于等待状态,只要它尝试删除另一个刚刚处理过的行。此等待仅在另一个提交或重新提交时结束