oracle 事務 與 提交


Oracle事務

一般事務(DML)即數據修改(增、刪、改)的事務
事務會將所有在事務中被修改的數據行加上鎖(行級鎖),來阻止其它人(會話)同時對這些數據的修改操作。
當事務被提交或回滾后,這些數據才會被釋放鎖。

舉個例子:
當A操作一條數據N1后,暫未提交事務 ,此時B又上來操作同一條數據N1,這時的情況是:
1、所有除A以外的人看不到被A所修改后的數據
2、B會處於等待狀態,直到A提交或回滾了針對這條數據的修改(這也就是行級鎖的概念)
3、當A提交事務后,所有人可以看到被A修改后的數據,看不到B修改后的數據。但B能看到自己修改后的數據(與A一樣,因為B還未提交事務)。
4、當B提交事務后,所有人可以看到被B修改后的數據。

由上可以看出,對同一條數據的事務處理,必須按先后順序進行。
即:A先提交了事務后,B才可以提交事務,否則B將無法對這條數據進行修改(B會在操作這條數據時處於等待狀態,直到A提交或回滾了事務,釋放了這行數據的鎖)。

這里注意一點,這里所說有A與B並不是指二個ORACLE帳戶,而是二個連接會話。上面只是為了方便舉例。
就是說即使是在同一台電腦上用同一個ORACLE帳戶,但同時分別打開了二個連接會話(比如同時打開二個PL/SQL並用相同帳戶連接到同一個庫中),就會被視為A、B兩個人。

在PS/SQL中,對數據修改完后,如果用戶未提交事務,但關閉或斷開了PS/SQL,此時ORACLE會立即提交此會話的事務。

我們可以事務中使用保存點來回滾到指定的時間節點上來,但如果用提交事務(commit)后,所有保存點將被刪除。

舉個舉子:

savepoint a1;    --設置一個保存點 a1;

update tmp set username='張三' where userid='101'  --修改一條數據

savepoint a2;   --設置一個保存點 a1;

update tmp set username='李四' where userid='102  --再修改一條數據

 

rollback to a2;   --回滾到a2 保存點。 此時在 a2 保存點之后的所有數據修改視為無效。

rollback to a1;   --這里可以再從a2保存點再回滾到a1 保存點。 此時在 a1 保存點之后的所有數據修改視為無效。

rollback;           --回滾全部。即撤消至上一次提交事務后的所有數據修改。

commit;  --提交事務 將回滾后的事務提交,並會刪除所有保存點。

注意:我們可以從a2向前再回滾到a1 ,但無法從a1回滾到a2。也就是只能向前回滾,不能從前面的點再向后回滾! 

只讀事務 即,只用於select 查詢的事務 

只讀事務主要用於在某一個時間點對數據的查詢統計。如:在18:00創建一個只讀事務,然后可以開始統計某張表的記錄數。此時18:00之后新添加到這張表中的數據就不會進入到統計中去。也就是創建只讀事務的會話連接人,將無法看到在創建只讀事務之后其它任何人對數據的真實修改。

方法是:

set transaction read only;  --在此之后,擁有此會話的連接人將無法看到其它人對數據的任何改動。用戶可以用select 進行此時間點的統計查詢

set transaction read write;  --取消只讀事務

只讀事務沒有回滾和提交的功能也不記錄回滾LOG。

只讀事務最大的用處是保證在某個時間點查詢結果的一致性。換句話說,如果你要統計很多信息,有多個select查詢時,但你執行完第一個查詢后(如用戶信息統計),可能其它人進來修改了某些數據你正在查詢的數據。這時你再進行第二個查詢(如用戶信息的統計或其它有關用戶信息的查詢)。這時候將出現數據查詢結果的不一致,第二次查詢的結果會由於數據被修改了而與第一次查詢結果一不樣。只讀事務正是解決這類問題的辦法。

其實ORACLE為了優化查詢在對於單條查詢時也會啟動只讀事務(就是在你開始執行查詢時會有一個只讀事務點,到查詢結束前,在這期間的數據修改都被無視掉),你無須手動創建只讀事務。但多條查詢時我們就必須手動創建只讀事務。

(來源:https://www.linuxidc.com/Linux/2012-07/66120.htm)

 

 

提交的類型:

提交數據有三種類型:
顯式提交、隱式提交及自動提交。
1、顯式提交:用COMMIT命令直接完成的提交為顯式提交。其格式為:SQL>COMMIT;
2、隱式提交:用SQL命令間接完成的提交為隱式提交。這些命令是:ALTER,AUDIT,COMMENT,CONNECT,CREATE,DISCONNECT,DROP,EXIT,GRANT,NOAUDIT,QUIT,REVOKE,RENAME。(此隱式提交是在自己的session,如果在其他人的session(如用戶a)中正在修改相同的數據,則引起隱式提交的語句(用戶a的k另一個session)則必需等待)
3、自動提交:若把AUTOCOMMIT設置為ON,則在插入、修改、刪除語句執行后,系統將自動進行提交,這就是自動提交。其格式為:SQL>SET AUTOCOMMIT ON;

查看當前是否是自動提交:show autocommit;

 

隱式提交:

隱式提交的定義 
又名自動提交,即無需顯示執行commit語句,session中的操作被自動提交到數據庫的過程。 
隱式提交的方式 
1、正常執行完ddl語句。包括create,alter,drop,truncate,rename。 
2、正常執行完dcl語句。包括grant,revoke。 
3、正常退出isql*plus,沒有明確發出commit或者rollback。 
隱式提交的注意事項 
1、執行ddl語句時,前面的dml操作也會被提交到數據庫中 
因為是在一個session里,那執行ddl語句的時候前面的dml語句肯定也會“不可幸免”的被提交到庫中。 
2、即使ddl語句執行失敗,前面的dml操作也會被提交到數據庫中 
這就有點兒讓人奇怪了,ddl都執行失敗了,怎么還會提交呢?這就需要探究一下隱式提交的本質了(下文有敘述)。 
3、在前面1和2的基礎上總結 
為了避免隱式提交或者回滾,盡量保證一條或者幾條DML操作完成后有顯示的提交或者回滾,防止后續執行的DCL或者DDL自動提交前期的DML操作。 
隱式提交的本質 
1、一條ddl語句執行了兩次commit 
commit; 
ddl statement; 
commit; 
第一個commit將當前session中未提交的事務隱式提交,以保證ddl語句失敗時的回滾位置。 
第二個commit將ddl 
2、為什么需要隱式提交? 
為了保證事務的一致性。我們在執行ddl語句的時候,oracle需要在它的系統表中進行元數據的記錄操作(即:除了建表還會進行不少insert操作),如果它不隱式提交就無法保證一致性;從內部運行機制來看ddl語句和dml語句還是有很大區別的,dml會對每個語句的每條記錄都做日志記錄以便於回滾,而ddl往往沒必要搞這么復雜,從功能和易用性上看隱式提交都是最好的選擇。 

(來源:https://www.linuxidc.com/wap.aspx?cid=7&nid=92704&sp=850)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM