您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關怎么在postgresql中使用for update對行級鎖進行測試,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
創建表:
CREATE TABLE db_user ( id character varying(50) NOT NULL, age integer, name character varying(100), roleid character varying, CONSTRAINT db_user_pkey PRIMARY KEY (id) )
隨便插入幾條數據即可。
1、打開一個postgreSQL的SQL Shell或pgAdmin的SQL編輯器窗口,執行:
begin;
select * from db_user where name='lisi';
輸出結果:
2、再打開一個postgreSQL的SQL Shell或pgAdmin的SQL編輯器窗口,執行:
begin;
select * from db_user where name='lisi';
輸出結果:
1、打開一個postgreSQL的SQL Shell或pgAdmin的SQL編輯器窗口,執行:
begin;
select * from db_user where name='lisi' for update;
輸出結果:
2、再打開一個postgreSQL的SQL Shell或pgAdmin的SQL編輯器窗口,執行:
begin;
select * from db_user where name='lisi' for update;
輸出結果:
查詢一直處于執行中狀態。
3、第一個窗口執行:
commit;
第二個窗口立即執行查詢操作,結果如下:
第二個窗口記得提交commit;。
1、打開一個postgreSQL的SQL Shell或pgAdmin的SQL編輯器窗口,執行:
begin;
select * from db_user where name='lisi' for update nowait;
輸出結果:
2、再打開一個postgreSQL的SQL Shell或pgAdmin的SQL編輯器窗口,執行:
begin;
select * from db_user where name='lisi' for update nowait;
輸出結果:
不會進行資源等待,返回錯誤信息。
3、第一個窗口執行:
commit;
提交成功,資源鎖釋放。
總結:
for update nowait和 for update 都會對所查詢到得結果集進行加鎖,所不同的是,如果另外一個線程正在修改結果集中的數據,for update nowait 不會進行資源等待,只要發現結果集中有些數據被加鎖,立刻返回 “55P03錯誤,內容是無法在記錄上獲得鎖.
命令說明:
begin;--開啟事務
begin transaction;--開啟事務
commit;--提交
rollback;--回滾
set lock_timeout=5000;--設置超時時間
注意:
連表查詢加鎖時,不支持單邊連接形式,例如:
select u.*,r.* from db_user u left join db_role r on u.roleid=r.id for update;
支持以下形式,并鎖住了兩個表中關聯的數據:
select u.*,r.* from db_user u, db_role r where u.roleid=r.id for update;
補充:PostgreSQL select for update指定列(兼容oracle)
我們可以使用select for update語句來指定鎖住某一張表,在oracle中我們可以在for update語句后指定某一列,用來單獨鎖定指定列的數據。
建表:
SQL> create table t1(id int, c2 varchar(20), c3 int, c4 float, c5 float); Table created. SQL> create table t2(id int, c6 int); Table created. SQL> insert into t1 values (1, 'SA_REP', 1, 100, 1); 1 row created. SQL> insert into t1 values (1, 'SA_REP123', 1, 100, 1); 1 row created. SQL> insert into t2 values (1, 2500); 1 row created.
查詢:
我們使用下列查詢用來只鎖住c4列。
SQL> SELECT e.c3, e.c4, e.c5 2 FROM t1 e JOIN t2 d USING (id) WHERE c2 = 'SA_REP' AND c6 = 2500 3 4 5 6 FOR UPDATE OF e.c4 7 ORDER BY e.c3; C3 C4 C5 ---------- ---------- ---------- 1 100 1
建表:
create table t1(id int, c2 text, c3 int, c4 float, c5 float); create table t2(id int, c6 int); insert into t1 values (1, 'SA_REP', 1, 100, 1); insert into t1 values (1, 'SA_REP123', 1, 100, 1); insert into t2 values (1, 2500);
pg中使用方法和oracle類似,只是需要將order by語法放到前面,并且將列名換成表名。
bill=# SELECT e.c3, e.c4, e.c5 bill-# FROM t1 e JOIN t2 d bill-# USING (id) bill-# WHERE c2 = 'SA_REP' bill-# AND c6 = 2500 bill-# ORDER BY e.c3 bill-# FOR UPDATE OF e ; c3 | c4 | c5 ----+-----+---- 1 | 100 | 1 (1 row)
驗證:
我們可以驗證下pg中是否只鎖定了指定的行。
1、安裝pgrowlocks插件
bill=# create extension pgrowlocks;
CREATE EXTENSION
2、觀察
t1表被鎖:
bill=# select * from pgrowlocks('t1'); locked_row | locker | multi | xids | modes | pids ------------+--------+-------+--------+----------------+-------- (0,1) | 1037 | f | {1037} | {"For Update"} | {2022} (1 row)
t2表沒有被鎖:
bill=# select * from pgrowlocks('t2'); locked_row | locker | multi | xids | modes | pids ------------+--------+-------+------+-------+------ (0 rows)
我們還可以再看看t1表中具體被鎖住的數據:
bill=# SELECT * FROM t1 AS a, pgrowlocks('t1') AS p bill-# WHERE p.locked_row = a.ctid; id | c2 | c3 | c4 | c5 | locked_row | locker | multi | xids | modes | pids ----+--------+----+-----+----+------------+--------+-------+--------+----------------+-------- 1 | SA_REP | 1 | 100 | 1 | (0,1) | 1037 | f | {1037} | {"For Update"} | {2022} (1 row)
除此之外,pg中for update子句還有其它的選項:
UPDATE – 當前事務可以改所有字段
NO KEY UPDATE – 當前事務可以改除referenced KEY以外的字段
SHARE – 其他事務不能改所有字段
KEY SHARE – 其他事務不能改referenced KEY字段
上述就是小編為大家分享的怎么在postgresql中使用for update對行級鎖進行測試了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。