W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
在由CALL
命令調(diào)用的過(guò)程中以及匿名代碼塊(DO
命令)中,可以用命令COMMIT
和ROLLBACK
結(jié)束事務(wù)。在一個(gè)事務(wù)被使用這些命令結(jié)束后,一個(gè)新的事務(wù)會(huì)被自動(dòng)開(kāi)始,因此沒(méi)有單獨(dú)的START TRANSACTION
命令(注意
BEGIN
和END
在PL/pgSQL中有不同的含義)。
這里是一個(gè)簡(jiǎn)單的例子:
CREATE PROCEDURE transaction_test1()
LANGUAGE plpgsql
AS $$
BEGIN
FOR i IN 0..9 LOOP
INSERT INTO test1 (a) VALUES (i);
IF i % 2 = 0 THEN
COMMIT;
ELSE
ROLLBACK;
END IF;
END LOOP;
END;
$$;
CALL transaction_test1();
新事務(wù)開(kāi)始時(shí)具有默認(rèn)事務(wù)特征,如事務(wù)隔離級(jí)別。在循環(huán)中提交事務(wù)的情況下,可能需要以與前一個(gè)事務(wù)相同的特征來(lái)自動(dòng)啟動(dòng)新事務(wù)。 命令COMMIT AND CHAIN
和ROLLBACK AND CHAIN
可以完成此操作。
只有在從頂層調(diào)用的CALL
或DO
中才能進(jìn)行事務(wù)控制,在沒(méi)有任何其他中間命令的嵌套CALL
或DO
調(diào)用中也能進(jìn)行事務(wù)控制。例如,如果調(diào)用棧是CALL proc1()
→ CALL proc2()
→
CALL proc3()
,那么第二個(gè)和第三個(gè)過(guò)程可以執(zhí)行事務(wù)控制動(dòng)作。但是如果調(diào)用棧是CALL proc1()
→ SELECT func2()
→ CALL proc3()
,則最后一個(gè)過(guò)程不能做事務(wù)控制,因?yàn)橹虚g有SELECT
。
對(duì)于游標(biāo)循環(huán)有特殊的考慮。看看這個(gè)例子:
CREATE PROCEDURE transaction_test2()
LANGUAGE plpgsql
AS $$
DECLARE
r RECORD;
BEGIN
FOR r IN SELECT * FROM test2 ORDER BY x LOOP
INSERT INTO test1 (a) VALUES (r.x);
COMMIT;
END LOOP;
END;
$$;
CALL transaction_test2();
通常,游標(biāo)會(huì)在事務(wù)提交時(shí)被自動(dòng)關(guān)閉。但是,一個(gè)作為循環(huán)的組成部分創(chuàng)建的游標(biāo)會(huì)自動(dòng)被第一個(gè)COMMIT
或ROLLBACK
轉(zhuǎn)變成一個(gè)可保持游標(biāo)。這意味著該游標(biāo)在第一個(gè)COMMIT
或ROLLBACK
處會(huì)被完全計(jì)算出來(lái),而不是逐行被計(jì)算。該游標(biāo)在循環(huán)后仍會(huì)被自動(dòng)刪除,因此這通常對(duì)用戶是不可見(jiàn)的。
有非只讀命令(UPDATE ... RETURNING
)驅(qū)動(dòng)的游標(biāo)循環(huán)中不允許有事務(wù)命令。
事務(wù)在一個(gè)具有異常處理部分的塊中不能被結(jié)束。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: