PostgreSQL 已读取已提交隔离级别。现在我有一个由单个 DELETE 语句组成的事务,这个 delete 语句有一个由 SELECT 语句组成的子查询,用于选择要删除的行。
我必须在 select 语句中使用 FOR UPDATE 才能与其他事务不发生冲突,这是真的吗?
我的想法如下:首先从表中读出相应的行,然后在第二步中删除这些行,因此另一个事务可能会干扰。
那么简单的 DELETE FROM myTable WHERE id = 4 语句呢?我还必须使用 FOR UPDATE 吗?
最佳答案
Is it true that I have to use FOR UPDATE in the select statement to get no conflicts with other transaction?
“不与其他交易发生冲突”对您来说意味着什么?您可以通过打开两个终端并在每个终端中执行语句来对此进行测试。正确交错后,DELETE 语句将使“其他事务”(隔离级别设置为 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=#
请参阅下面的文档。
And what about a simple DELETE FROM myTable WHERE id = 4 statement? Do I also have to use FOR UPDATE?
没有 DELETE 这样的语句。 . .更新
。
当您阅读有关数据库更新的信息时,您需要对上下文敏感。 更新 可以表示对数据库的任何更改;它可以包括插入、删除和更新行。在下面引用的文档中,“像更新一样锁定”明确地谈论 UPDATE 和 DELETE 语句等。
FOR UPDATE causes the rows retrieved by the SELECT statement to be locked as though for update. This prevents them from being modified or deleted by other transactions until the current transaction ends. That is, other transactions that attempt UPDATE, DELETE, SELECT FOR UPDATE, SELECT FOR NO KEY UPDATE, SELECT FOR SHARE or SELECT FOR KEY SHARE of these rows will be blocked until the current transaction ends. The FOR UPDATE lock mode is also acquired by any DELETE on a row, and also by an UPDATE that modifies the values on certain columns. Currently, the set of columns considered for the UPDATE case are those that have an unique index on them that can be used in a foreign key (so partial indexes and expressional indexes are not considered), but this may change in the future. Also, if an UPDATE, DELETE, or SELECT FOR UPDATE from another transaction has already locked a selected row or rows, SELECT FOR UPDATE will wait for the other transaction to complete, and will then lock and return the updated row (or no row, if the row was deleted).
关于PostgreSQL for 更新语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26117045/