您好,登錄后才能下訂單哦!
這篇文章主要介紹“怎么理解Oracle的lock和latch”,在日常操作中,相信很多人在怎么理解Oracle的lock和latch問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么理解Oracle的lock和latch”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
在開發多用戶,數據庫驅動的應用時,最大的難點之一是:一方面要力爭最大限度的并發訪問,與此同時還要確保每個用戶保證用戶一致性的前提下讀取和修改數據。所以就出現了鎖(lock)這個機制。
鎖(lock)用于管理對共享資源的并發訪問。舉一個很形象的例子:
user1 在它的session中的一個事務獲取了一個一行數據,放在本地的內存,顯示給了user1;
user2在它的session中的一個事務也獲取了這個數據,顯示給user2;
user1 使用它的應用修改了這行數據,然后commit之后,session中的該事務已經完成
user2也修改了這行數據,commit之后,完成該項事務
這個過程知之為“更新丟失”,因為user1所做的修改將會全部丟失。所以這種情況,Oracle便有了鎖這種設定,而鎖也有兩種策略:悲觀鎖(pessimistic)和樂觀鎖(optimistic)
悲觀鎖
悲觀鎖,顧名思義,Oracle認為你只要有會話連接,怕其他會話一定會進行數據上的修改,所以只要有session的事務牽涉到數據表,Oracle便會對其加一個行鎖,防止其他用戶對其修改,直到該session 中的事務提交完成。
會話便會一直在這等待,此時在user1中 commit后,user2便會執行并報出相應結果!悲觀鎖可以讓user非常安全的對該行數據進行操作,能確保我們再進行修改之前沒人對他進行其他操作。
樂觀鎖
樂觀鎖跟悲觀鎖是對立的,悲觀鎖認為可能有其他會話對我正在處理的數據進行操作,而樂觀鎖則認為所有會話都是友好的,不會對數據進行花里胡哨的操作。所以我們可以修改自己的數據,直到我們commit的時候才會發現我們的想法對不對。
例如我們再執行一個update語句時候,更新語句成功則說明,我們很幸運,這期間沒有其他會話對其進行操作;如果最后顯示的是 更新0行,這就說明另外的user修改了數據。所以需要我們考慮如果出現這種情況下下一步應該怎么處理。
這里先討論一種使用樂觀鎖的方法:使用版本列的樂觀鎖
用簡單一點的話概括就是,為原始數據做一個獨一無二的標記,然后用更新數據后的標記與原始數據的標記相對比,如果相同的話,說明無人改動,則更新成功;如果不同的話則更新失敗。 這種使用版本列的樂觀鎖難點就在于如何更新我們的‘版本列’。但是這個問題在oracle中倒是很容易解決。只需在對應的每個表上添加以number 或date/timestamp類型的列,然后通過表上的行觸發器或者存儲過程來維護。(觸發器會在修改操作之外增加額外開銷,慎用!)
那究竟是使用樂觀鎖還是悲觀鎖呢?事實上,悲觀鎖在處理并發時工作得很好,但是在如今的高并發的各種應用中,悲觀鎖要對事務始終保持連接 ,這個代價太大了,也就是我們常說的利大于弊,所以,在目前大多數應用中,多數采用的是樂觀鎖并發控制,并且使用版本列的樂觀鎖這種方法。
在Oracle中主要有三類鎖,DML鎖,DDL鎖,內部鎖和閂:我們先主要介紹一下DML鎖
DML鎖用于確保一次只有一個人能修改某一行;Oracle 會一種比較透明的方式添加這種鎖。
TX鎖
當事務發起了第一個修改時會得到一個TX鎖(事務鎖),該TX鎖會一直擁有直到事務提交。TX鎖作為一種排隊機制,使得其他會話可以等待該事務完成。由于鎖是事務的一個屬性,所只要事務找到了數據,而數據沒有被鎖定,則對其鎖定。如果數據被鎖定了,則請求鎖的會話將會等待,等待目前擁有鎖的事務執行,然后得到數據。
TM鎖
TM鎖用于確保修改表內容時,表的結構不變;例如在我更新了表中一行數據的時候,我同時會得到這張表上的一個TM鎖;防止其他用戶對該表執行drop或者alter的命令。
說完了鎖的工作原理以及其兩種鎖機制,接下來講講閂(latch)
閂(latch)是一種輕量級的串行設備,用于協調對共享數據結構、對象和文件的多用戶訪問。閂是一種鎖,而鎖是一種串行化的設備,所以為了更好的擴展應用,就必須尋找合適的方法減少閂(鎖)的數量。
為什么說閂是種輕量級的鎖,因為閂的設計只為了持有一小段時間,而不是因為他影響小被稱為輕量級,事務一般會在內部以一種“愿意等待”的姿態去請求閂。如果沒請求道閂,則該會話會休眠一段時間,然后再嘗試這個請求操作,這里的機制是休眠不用排隊;而隊列鎖(enqueue)則允許請求者排隊者等待資源,所以請求者會出現阻塞。話題轉回來,閂允許會話休眠,然后再讓該會話再次請求該資源;這里就涉及到閂的特殊操作:自旋(spin):就是在不斷嘗試得到閂。因為上下文切換(context switching:指被踢出CPU,然后又要必須調度回到cpu中)的資源消耗很大,所以進程不能立即得到閂的話,我們會讓該進程一直在cpu里不出去,一直嘗試得到閂;因為閂設計的就是極短時間內的設定,所以說持有閂的會話會很快的放棄閂,讓其他進程得到閂;如果一直得不到閂的話,該會話才會放棄cpu,讓其他進程享用資源,自己進行休眠。
這個休眠的動作一般是多個會話同時請求同一個閂才會發生,雖然每個持有的時間很短,但是數量一多,累加起來時間就長了。
到此,關于“怎么理解Oracle的lock和latch”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。