oracle restart 語句重新執行

2021-08-27 15:33:47 字數 2377 閱讀 1757

今天看了tom大師關於sql restart的部落格,收益頗深。鑑於的繁瑣和以後查閱的方便,將主要內容總結至此。大家也可以通過如下位址檢視原博文及精彩點評(需要哦)。

大家都知道oracle通過一致性讀來防止阻塞並為查詢提供結果。但是對於寫或者說編輯操作,oracle是怎樣處理的那?例如下面的語句:

update t set x=2 where y=5;

對於這樣的語句,oracle首先會根據語句的執行起始時間t1和where條件進行基於t1的一致性查詢操作,找出y=5的所有記錄,然後對這些記錄進行更新操作。那麼這裡就存在乙個問題,假設在t2時間,oracle修改到記錄r,如果在t1和t2之間的時間段裡,某個使用者程序修改了記錄r並進行了提交,此時oracle會做如何處理那?我們知道,讀操作我們可以基於以往時間點構造一致性塊,但是對於寫操作,我們必須對當前塊進行操作。

首先我們在表tab上建立觸發器

sql> create or replace trigger tab_tri

2 before update on tab for each row

3 begin

4 dbms_output.put_line(' old.x = '||:old.x||',old.y ='||:old.y);

5 dbms_output.put_line(' new.x = '||:new.x||',new.y ='||:new.y);

6 end;

7 /

session1:更新某記錄,不提交

sql> update tab set x=2 where y=1;
session2:更新相同記錄,程序被阻塞

sql> update tab set x=3 where y=1;
session2:session1提交後

sql> update tab set x=3 where y=1;

old.x = 1,old.y =1

new.x = 3,new.y =1

old.x = 2,old.y =1

new.x = 3,new.y =1

已更新 1 行。

從這裡可以看出,如果更新r時,oracle發現r已經被修改過,那麼oracle會重新執行update語句。

下面讓我們修改一下觸發器

sql> create or replace trigger tab_tri

2 before update on tab for each row

3 begin

4 dbms_output.put_line('aaaaa');

5 end;

6 /

session2:在session1提交後:

sql> update tab set x=3 where y=1;

aaaaa

已更新 1 行。

非常奇怪?這裡update語句並沒有重新執行

下面在來改變一下執行語句:

sesion1:

sql> update tab set y=2 where y=1;

已更新 1 行。

session2:

sql> update tab set x=3 where y>0;

aaaaa

aaaaa

這裡update語句再次重新執行。好,我們總結如下:

如果在update(delete沒有測試,估計應該是相同的)語句的執行過程中,待操作記錄發生了改變,並且被改變的列在where子句或者row觸發器(after or before)的內部使用:old或者:new引用過,那麼update語句會將之前的操作回滾並重新執行。這也是after觸發器效率高於before觸發器的乙個原因,因為即便update重新執行,after觸發器只執行一次,而befer觸發器會執行兩次。如果發生了restart,oracle會在第二次執行的過程中嘗試使用select for update來進行操作,以避免發生再一次的restart。但是即便使用select for update ,依然有可能發生restart。

下面看一下restart產生的影響:

1:如果觸發器維護plsql中的全域性變數,那麼全域性變數可能是不準確的

2:任何utl_函式,例如utl_file, utl_http, utl_smtp,可能會執行兩次,因此這些函式時非事務性的,無法回滾

3:自治事務當然也會受影響而執行多次

語句 switch語句

switch語句的特點如下 1 switch x 被選擇的內容 即x 只能是byte,short,int,char這四種型別 2 備選答案並沒有指定的順序,但是執行肯定是從第乙個case開始的,如果其中有匹配的case,執行完,通過該case的break就結束了switch。如果沒有匹配的case,...

Python while語句,for語句

usr bin python coding utf 8 filename whiletest.py num 23running true while running i int raw input input a number if i num print right running false e...

迴圈for語句 if語句

if語句 if 表示式 else if 表示式 for迴圈 for var i 0 i 10 i if語句 if 表示式 else if 表示式 for迴圈 for var i 0 i 10 i while迴圈 while 表示式 使用場景 for 次數確定的時候使用 while 直到滿足摸個條件的...