[英]lock the rows until next select postgres
在postgres中有沒有一種方法可以鎖定行,直到同一系統中的下一個選擇查詢執行為止。 還有一件事是,鎖定的行將沒有更新過程。 場景是這樣的
如果table1包含如下數據
id | txt
-------------------
1 | World
2 | Text
3 | Crawler
4 | Solution
5 | Nation
6 | Under
7 | Padding
8 | Settle
9 | Begin
10 | Large
11 | Someone
12 | Dance
如果sys1執行
select * from table1 order by id limit 5;
那么對於同時執行select語句的其他系統,它應該將ID從1到5的行鎖定。
稍后,如果sys1再次執行另一個選擇查詢,例如
select * from table1 where id>10 order by id limit 5;
然后應該釋放以前鎖定的行。
我認為這是不可能的。 您不能阻止對表的只讀訪問(除非選擇已完成FOR UPDATE
)
據我所知,您唯一的機會就是使用pg_advisory_lock()
函數。
http://www.postgresql.org/docs/current/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS
但是,這需要“手動”釋放通過它獲得的鎖。 這樣您將不會獲得自動解鎖。
要鎖定行,您將需要以下內容:
select pg_advisory_lock(id), * from ( select * table1 order by id limit 5 ) t
(請注意在LIMIT部分使用派生表。請參閱我發布的手冊鏈接以獲取解釋)
然后,您需要存儲檢索到的ID,然后為每個ID調用pg_advisory_unlock()
。
如果每個進程總是一次釋放所有 ID,則可以簡單地使用pg_advisory_unlock_all()
。 然后,您將不需要存儲檢索到的ID。
請注意,這不會阻止其他人使用“正常”選擇讀取行。 僅當訪問該表的每個進程使用相同的獲取鎖的模式時,它才起作用。
看起來您確實有一個超越數據庫邊界的事務,並且所有更改都發生在另一個系統中。
我的想法是select ... for update no wait
鎖定相關行,然后將數據卸載到另一個系統中,然后rollback
以解鎖行。 沒有兩個select ... for update
查詢的select ... for update
將選擇同一行,第二個select
將立即失敗,而不是等待並繼續。
但是您似乎並沒有以任何方式標記卸載的記錄。 我不明白為什么兩個不連續的選擇不會愉快地選擇重疊范圍。 因此,我仍然會使用標志和/或目標用戶名來update
記錄,並且只會選擇未設置標志的記錄。
我同時嘗試了select ... for update和pg_try_advisory_lock並設法接近我的要求。
/*rows are locking but limit is the problem*/
select * from table1 where pg_try_advisory_lock( id) limit 5;
.
.
$_SESSION['rows'] = $rowcount; // no of row to process
.
.
/*afer each process of word*/
$_SESSION['rows'] -=1;
.
.
/*and finally unlock locked rows*/
if ($_SESSION['rows']===0)
select pg_advisory_unlock_all() from table1
但是這有兩個問題
1.由於限制將在鎖定之前應用,因此每次相同的行嘗試在不同的實例中鎖定時。
2.不確定pg_advisory_unlock_all將解鎖當前實例或所有實例鎖定的行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.