Oracle事務與鎖 知識點摘記
事務:事務用於保證數據的一致性,它由一組相關的dml語句組成,該組的dml語句要麽全部成功要麽全部失敗。
說明:一組SQL,一個邏輯工作單位,執行整體修改或者整體回退。
事務的相關概念:
1、事務的提交和回滾:COMMIT/ROOLLBACK
2、事務的開始和結束:
開始事務:連接到數據庫,執行DML,DCL,DDL語句
結束事務: 1)執行DDL(例如CREATE TABLE),DCL(例如GRANT),系統自動執行COMMIT語句
2)執行COMMIT/ROLLBACK
3)退出/斷開數據庫的連接自動執行COMMIT語句
4)進程意外終止,事務自動rollback
5)事務COMMIT時會生成一個唯一的系統變化號(SCN)來保存到事務表
保存點(savepoint): 可以在事務的任意位置設置保存點,以便於ROLLBACK
事務的四個特性ACID:
1)Atomicity(原子性):事務中sql語句不可分割,要麽全部做,要麽全部不做
2)Consistency(一致性):指事務操作前後數據庫中的數據是一致的,數據滿足業務規則約束(例如賬戶金額的轉出和轉入),與原子性對應
3)Isolation(隔離性):多個並發事務可以獨立運行,而不能相互幹擾,一個事務修改數據未提交前,其他事務不能看到它所進行的修改
4)Durability(持久性):事務提交後,數據的修改是永久的
死鎖:當兩個事務相互等待對方釋放資源時候就會形成死鎖
兩個並發事務同時訪問數據庫表相同的行時,可能存在以下三個問題:
1、幻想讀:事務T1讀取一條指定where條件的語句,返回結果集。此時事務T2插入一行新記錄,恰好滿足T1的where條件。然後T1使用相同的條件再次查詢,結果集中可以看到T2插入的記錄,這條新紀錄就是幻想。
2、不可重復讀取:事務T1讀取一行記錄,緊接著事務T2修改了T1剛剛讀取的記錄,然後T1再次查詢,發現與第一次讀取的記錄不同,這稱為不可重復讀。
3、臟讀:事務T1更新了一行記錄,還未提交所做的修改,這個T2讀取了更新後的數據,然後T1執行回滾操作,取消剛才的修改,所以T2所讀取的行就無效,也就是臟數據。
為了處理這些問題,SQL標準定義了以下幾種事務隔離級別
READ UNCOMMITTED 幻想讀、不可重復讀和臟讀都允許。
READ COMMITTED 允許幻想讀、不可重復讀,不允許臟讀
REPEATABLE READ 允許幻想讀,不允許不可重復讀和臟讀
SERIALIZABLE 幻想讀、不可重復讀和臟讀都不允許
事務和鎖:
當執行事務操作時(dml語句),Oracle會在被作用的表上加鎖,防止其他用戶修改表的結構,這對我們用戶來說是非常重要的
所謂死鎖:是指兩個或兩個以上的進程在執行過程中,因為爭奪資源而造成的相互等待現象,若無外力作用,這些進程都將無法進行下去
此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在相等待的進程稱為死鎖進程
由於資源占用是互斥的,當某個進程提出申請資源呢後,使得有關進程在無外力協助的情況下,永遠分配不到資源而無法繼續運行下去,就產生了這一特殊的死鎖現象
數據庫死鎖的現象:程序執行的過程中,點擊確定或者保存按鈕,程序沒有響應,也沒提示錯誤
死鎖的原理: 對於數據庫某個表的某一列做更新或者刪除操作,執行完畢後該條語句不提交,另一條對於這一列數據做更新操作的語句在執行的時候就會進入等待狀態,此時的現象就是這條語句一直在執行但是一直不能執行成功,也不會報錯
解決方法: 將產生死鎖的語句提交即可,但是在執行的過程中,用戶可能不知道產生死鎖的語句是哪一句,可以將程序關閉並重新啟動即可
鎖包括行級鎖、表級鎖、悲觀鎖、樂觀鎖
行級鎖:一種它鎖,防止另外事務修改此行;在使用以下語句時,Oracle會自動應用行級鎖:INSERT、UPDATE、DELETE、SELECT … FOR UPDATE [OF columns] [WAIT n | NOWAIT];SELECT … FOR UPDATE語句允許用戶一次鎖定多條記錄進行更新.使用commit或者rollback釋放鎖。 特點:開鎖大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖沖突的概率最低,並發度也最高。適合於有大量按索引更新少量不同數據,同時又有並發查詢的應用,如一些在線事務處理系統。
表級鎖:5種
共享鎖(SHARE) - 鎖定表,對記錄只讀不寫,多個用戶可以同時在同一個表上應用此鎖,在表沒有被任何DML操作時,多個事務都可加鎖,但只有在僅一個事務加鎖的情況下只有此事務才能對表更新;當表已經被更新或者指定要更新時(select for update),任何事務都不能加此鎖了。
共享行排他(SHARE ROW EXCLUSIVE) – 比共享鎖更多的限制,禁止使用共享鎖及更高的鎖,在表沒有被任何DML操作時,只有一個事務可以加鎖,可以更新,書上說別的事務可以使用select for update鎖定選中的數據行,可是實驗後沒被驗證。
排他(EXCLUSIVE) – 限制最強的表鎖,僅允許其他用戶查詢該表的行。禁止修改和鎖定表
行共享 (ROW SHARE) – 禁止排他鎖定表,與行排他類似,區別是別的事務還可以在此表上加任何排他鎖。(除排他(exclusive)外)
行排他(ROW EXCLUSIVE) – 禁止使用排他鎖和共享鎖,其他事務依然可以並發地對相同數據表執行查詢,插入,更新,刪除操作,或對表內數據行加鎖的操作,但不能有其他的排他鎖(自身是可以的,沒發現有什麽用)
悲觀鎖:Pessimistic Lock正如其名,它指的是對數據被外界(包括本系統當前的其他事務,以及來自外部系統的事務處理)修改持保守悲觀態度,事務每次去操作數據的時候都假設有其他事務會修改需要訪問的數據,所以在訪問之前都要求上鎖,行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖,因此,在整個數據處理過程中,將數據處於鎖定狀態。
一個典型的倚賴數據庫的悲觀鎖調用: select * from account where name=”Erica” for update 這條sql 語句鎖定了account 表中所有符合檢索條件(name=”Erica”)的記錄。 本次事務提交之前(事務提交時會釋放事務過程中的鎖),外界無法修改這些記錄。
樂觀鎖:Optimistic Lock,和悲歡鎖相反,事務每次去操作數據之前,都假設其他事務不會修改這些需要訪問的數據 ,所以 在訪問之前不要求上鎖,只是在進行更新修改操作的時候判斷一下在訪問的期間有沒有其他人修改數據 了。它適用於多讀的應用類型,沖突真的發生比較少的時候就比較好,這樣省去了開銷的開銷,可以提高吞吐量;但如果是真的經常要發生沖突的,那每次還要去判斷進行retry,反倒降低的性能,這個時候悲歡鎖比較好。數據庫如果提供類似於write_condition機制的其實都是提供的樂觀鎖。
提交事務:
當使用COMMIT語句可以提交事務,當執行了COMMIT語句後,會確認事務的變化、結束事務、刪除保存節點、釋放鎖,當使用COMMIT語句結束事務後,其它會話將可以查看到事務變化後的新數據
回退事務:
在介紹回退事務前,先介紹一下保存點(savepoint)的概念和作用,保存點是事務中的一個點,用於取消部分事務,當結束事務時,會自動刪除該事務所定義的所有保存點.當執行rollback時,通過指定保存點可以回退到指定的點.
內容參考於:https://www.cnblogs.com/lingyejun/p/7096791.html
Oracle事務與鎖 知識點摘記