我有這個代碼示例,它應該在 postgres 中使用行(元組)鎖,但是它似乎使用了表(關系)鎖:
with transaction.Atomic(savepoint=True, durable=False):
record = MyModel.objects.select_for_update().filter(pk='1234')
record.delete()
time.sleep(5)
raise Exception
通過查看事務期間的 pg_locks,我可以看到:
select locktype, database, relation::regclass, pid, mode, granted from pg_locks where pid <> pg_backend_pid();

據我所知,我應該在鎖型別中看到“元組”,因為我只鎖定特定的行而不是整個表
uj5u.com熱心網友回復:
第一件事
您實際上沒有執行SELECT FOR UPDATE查詢。
record = MyModel.objects.select_for_update().filter(pk='1234')回傳 aQuerySet,不執行任何查詢。record.delete()只執行一個DELETE命令。
- 一
SELECT FOR UPDATE查詢就會取得relationRowShareLock。- 您可以通過執行
QuerySetwith來驗證這一點.first(),即record = MyModel.objects.select_for_update().filter(pk='1234').first()。
- 您可以通過執行
- 您可以通過記錄所有 sql 查詢來驗證這一點。
行級(元組)鎖
FOR UPDATE已獲取行級鎖但未顯示在您的pg_locks視圖中(它也未顯示在我的視圖中)。相反,我們看到transactionid ExclusiveLock(和virtualxid ExclusiveLock)。
從https://www.postgresql.org/docs/9.3/view-pg-locks.html:
盡管元組是一種可鎖定型別的物件,但有關行級鎖的資訊存盤在磁盤上,而不是存盤在記憶體中,因此行級鎖通常不會出現在此視圖中。如果一個事務正在等待一個行級鎖,它通常會出現在視圖中,等待該行鎖當前持有者的永久事務 ID。
從https://www.postgresql.org/docs/9.4/explicit-locking.html:
FOR UPDATE...
在
FOR UPDATE鎖定模式也取得任何DELETE某行...
您可以通過在 psql 終端中運行來憑經驗驗證這一點:
- 前
record.delete()SELECT FROM mymodel WHERE id='1' FOR UPDATE;作品。SELECT FROM mymodel WHERE id='1234' FOR UPDATE;作品。
- 后
record.delete()SELECT FROM mymodel WHERE id='1' FOR UPDATE;作品。SELECT FROM mymodel WHERE id='1234' FOR UPDATE;不起作用。
表級(關系)鎖
- 在
relationAccessShareLock出現被收購的SELECT查詢,你沒有你的代碼示例,例如,在顯示MyModel.objects.filter(pk='1234').first()。 - 該
relationRowExclusiveLock獲取的DELETE命令。
雖然這些是表級鎖,但它們僅與EXCLUSIVE和/或ACCESS EXCLUSIVE鎖沖突,大多數其他 DQL(資料查詢語言)和 DML(資料操作語言)命令不會獲取它們。
從https://www.postgresql.org/docs/9.4/explicit-locking.html:
ACCESS SHARE
ACCESS EXCLUSIVE僅與鎖定模式沖突。該
SELECT命令在參考的表上獲取此模式的鎖。一般來說,任何只讀取一個表而不修改它的查詢都會獲得這種鎖模式。
ROW EXCLUSIVE與
EXCLUSIVE和ACCESS EXCLUSIVE鎖定模式沖突。The commands
UPDATE,DELETE, andINSERTacquire this lock mode on the target table (in addition toACCESS SHARElocks on any other referenced tables). In general, this lock mode will be acquired by any command that modifies data in a table.
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/353003.html
標籤:姜戈 PostgreSQL django-orm 选择更新
