溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Oracle 鎖機(jī)制學(xué)習(xí)

發(fā)布時(shí)間:2020-08-03 13:27:54 來源:網(wǎng)絡(luò) 閱讀:424 作者:張marlie 欄目:關(guān)系型數(shù)據(jù)庫

鎖的簡介

  Oracle實(shí)現(xiàn)并發(fā)訪問控制,通過鎖來實(shí)現(xiàn)。

  鎖分為悲觀鎖(事務(wù)調(diào)度可能會(huì)串行調(diào)度)--事務(wù)級(jí)別的行級(jí)鎖。

      樂觀鎖(事務(wù)被串行調(diào)度)-- 時(shí)間戳和基于驗(yàn)證的事務(wù)調(diào)度。

  所謂樂觀鎖是指事務(wù)調(diào)度串行機(jī)制不會(huì)打亂,保證每個(gè)事務(wù)之間數(shù)據(jù)更改彼此不會(huì)受影響,維護(hù)數(shù)據(jù)一致性。

  Oracle默認(rèn)隱式執(zhí)行鎖定機(jī)制,采用影響行數(shù)最少的行級(jí)鎖,在數(shù)據(jù)庫塊中存儲(chǔ)鎖定行的信息。

  鎖針對(duì)某個(gè)事務(wù)的整個(gè)過程,在發(fā)出commit或rollback后鎖自動(dòng)消失。

鎖的鎖定方法

  Oracle采用行級(jí)粒度的方式來進(jìn)行鎖定對(duì)象,一個(gè)事務(wù)操作影響幾條數(shù)據(jù)就鎖定幾行。

  粒度越小,支持的并發(fā)越大。

鎖類型

  鎖的對(duì)象可以是用戶級(jí)的表、索引等,也可是共享數(shù)據(jù)結(jié)構(gòu)(數(shù)據(jù)字典)。

  1. DML鎖

    針對(duì)保護(hù)用戶的表和索引,在事務(wù)操作的行上加了一把獨(dú)占行級(jí)鎖,防止相同數(shù)據(jù)行同時(shí)被多個(gè)事務(wù)同時(shí)更改,在一事務(wù)未提交前,后一事務(wù)只能等待直到前一事務(wù)提交。

    在DML鎖的同時(shí)會(huì)持有一個(gè)DDL表鎖,在DML(insert,update,delete)操作時(shí)另一事務(wù)不能對(duì)表進(jìn)行定義表結(jié)構(gòu)操作。同一事務(wù)可以操作,等待時(shí)間取決于操作ddl_lock_timeout

    此參數(shù)默認(rèn)值為0

    show parameter ddl_;

    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------
    ddl_lock_timeout                     integer     0



    可以在session級(jí)別設(shè)定等待事件

    alter session set ddl_lock_timeout = 30;

    -- 設(shè)定同一事務(wù)ddl鎖等待dml鎖的時(shí)間為30秒,默認(rèn)為不等待立即執(zhí)行。

    操作等待時(shí)間超過設(shè)定值直接失效。前提是dml操作時(shí)間很長,超過了ddl等待時(shí)間。

  2. DDL鎖

    在DML鎖時(shí)有附帶對(duì)應(yīng)表的DDL鎖

  3. 閂用于保護(hù)sga中共享數(shù)據(jù)結(jié)構(gòu),控制對(duì)內(nèi)存結(jié)構(gòu)的訪問。

  4. 數(shù)據(jù)字典鎖

    字典對(duì)象被修改時(shí)的對(duì)應(yīng)的鎖

  5. 分布鎖

    在RAC結(jié)構(gòu)或分布式系統(tǒng)中使用的鎖

  6. 內(nèi)部鎖

    Oracle為保護(hù)訪問數(shù)據(jù)文件、表空間、回滾段而使用的鎖


鎖管理:

在實(shí)際應(yīng)用系統(tǒng)中,會(huì)出現(xiàn)進(jìn)程等待現(xiàn)象,這是阻塞鎖導(dǎo)致,有人俗稱‘死鎖’這是錯(cuò)誤的。

死鎖 是兩個(gè)進(jìn)程彼此等待,造成的死循環(huán)。阻塞鎖是一個(gè)進(jìn)程等待另外一個(gè)進(jìn)程,當(dāng)前一進(jìn)程提交或回滾后,后一進(jìn)程就能得到對(duì)應(yīng)對(duì)象的控制權(quán)。

死鎖有Oracle內(nèi)部處理,殺死后請(qǐng)求事務(wù),無需人為參與

  1. 阻塞鎖

    當(dāng)一個(gè)事務(wù)在某個(gè)對(duì)象上的鎖阻止或阻塞了其他事務(wù)訪問相同對(duì)象時(shí),阻塞鎖就會(huì)出現(xiàn)。

    在視圖 dba_blocks中可查詢當(dāng)前被阻塞的會(huì)話ID

    select * from dba_blockers;

    HOLDING_SESSION
    ---------------
                 39

    也可在v$session視圖中查詢當(dāng)前阻塞的會(huì)話

    select t.SID,t.USERNAME,t.BLOCKING_SESSION_STATUS,t.BLOCKING_SESSION from v$session  t
    where t.BLOCKING_SESSION_STATUS = 'VALID';

           SID USERNAME                       BLOCKING_SE BLOCKING_SESSION
    ---------- ------------------------------ ----------- ----------------
            42 halee                           VALID                     39


  2. 死鎖

    兩個(gè)事務(wù)同時(shí)對(duì)相同對(duì)象持有行級(jí)獨(dú)占鎖,彼此阻塞就會(huì)形成死鎖。Oracle自動(dòng)殺死對(duì)改對(duì)象鎖的后持有者

  3. 管理視圖

    dba_blockers -- 記錄當(dāng)期庫中阻塞其他進(jìn)程的進(jìn)程

    dba_waiters -- 記錄等待進(jìn)程,被阻塞進(jìn)程,鎖類型,即將請(qǐng)求的鎖類型

    select * from dba_waiters;
    WAITING_SESSION HOLDING_SESSION LOCK_TYPE   MODE_HELD  MODE_REQUESTED LOCK_ID1 LOCK_ID2
    --------------- --------------- ---------   ---------  ----------     -------  ------
         42           39            Transaction  Exclusive  Exclusive       39214  2964

    dba_locks -- 記錄每個(gè)會(huì)話具體的鎖類型

  4. 生成庫中鎖的情況

    執(zhí)行安裝目錄下的utllockt.sql文件,可以生成對(duì)應(yīng)鎖等待的具體情況

    WAITING_SESSION   LOCK_TYPE         MODE_REQUESTED  MODE_HELD       LOCK_ID1          LOCK_ID2
    ----------------- ----------------- --------------- --------------- ----------------- -----------------
    39                None
       42             Transaction       Exclusive       Exclusive       393241            2964

    返回結(jié)果說明:
    會(huì)話42在等待會(huì)話39提交或回滾來回去行獨(dú)占鎖

    可采用如下sql 查詢對(duì)應(yīng)鎖對(duì)應(yīng)的操作

    SELECT /*+ ORDERED */sql_text
FROM v$sqltext a
WHERE (a.hash_value, a.address) IN (
SELECT DECODE (sql_hash_value,
0, prev_hash_value,
sql_hash_value
),
DECODE (sql_hash_value, 0, prev_sql_addr, sql_address)
FROM v$session b,dba_blockers c
WHERE b.SID = c.holding_session);

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI