Posted on 2010-02-19 22:23
landor 閱讀(1520)
評論(0) 編輯 收藏 所屬分類:
oracle
oracle的鎖并沒有鎖升級,也就是無論有多少行數據被鎖定也不會升級到表鎖,這和sqlserver完全不一樣
oracle鎖類型包括:DML鎖、DDL鎖、內部鎖和閂
DML鎖:數據庫操作語言鎖,比如insert、delete、update語句引發的鎖。當進行上述操作時,會出現兩種DML鎖:
TX鎖:事務鎖,當事務發起第一次修改時會出現TX鎖,直到事務的提交或回滾時釋放鎖,當執行select for update的時候也會引發;
TM鎖:當數據被修改時,為防止出現表結構的變化,比如alter、drop操作,所加的鎖,這時如果有其他事務修改表結構,會返回錯誤信息ORA-00054。
TX鎖:當修改表中某一行或者某十行數據時,會在包含該數據的塊中記錄當前事務的id。此時如果另會話2進入,要修改當前記錄時,會檢查當前塊中的事務id,然后到事務表中查看該事務是否活動,如果不活動,那么會話2會修改該行并鎖定該行;如果活動那么會話2會發出一個request,要求會話1釋放鎖的時候通知會話2一聲。
這里涉及到了3個表:V$TRANSACTION(事務表),V$SESSION(會話表)、V$LOCK(鎖信息)
這里記錄一下V$LOCK表,這里面的記錄是針對表和會話的,而不是針對行的,如果表有1條記錄被鎖定,那么V$LOCK中會有一條記錄,如果表中有10條記錄被鎖定,那么V$LOCK中還是一條,因為它是針對于會話的。
在表V$LOCK的SID就是會話id,而通過id1和id2可以匹配到V$TRANSACTION中的事務id
舉個例子:如果事務1鎖定了一個表的10行記錄,那么V$LOCK中會有一條記錄,其中LMODE為6,表示排他鎖,REQUEST為0,表示事務1并沒有發出請求,也就是說事務1可以擁有這個鎖;
此時事務2也要鎖定這10行記錄中的若干行,結果發現該行已經被事務1鎖住了,事務2只能向事務1發出請求REQUEST=6,意思是事務2向事務1發出一個排他鎖的請求,此時在V$LOCK表中有三條記錄,一條是事務2的排他鎖,一條是事務2向事務1發出的request請求,一條是事務1的排他鎖。當事務1提交或者回滾釋放鎖后,V$LOCK中事務2的那個請求行消失,事務2獲取了該行的排他鎖。
DDL鎖:數據庫定義語言鎖,當進行表的alter等操作時,會觸發該鎖,防止其他會話(session)獲取到這個表的DDL鎖或者DML鎖中的TM鎖。
DDL語句是總是提交的,比如有3個alter語句,那么每個都是自動提交的,比如第二個出現錯誤,那么第一個也已經提交了,無法回滾了
關于oracle的事務處理
ACID是下面的4個詞:
原子性:事務中的所有動作要么都發生,要么都不發生
一致性:事務將數據庫從一種狀態轉換為另一種狀態
隔離性:一個事務的影響在該事務提交前,對其他事務是不可見的
持久性:事務一旦提交,其影響的結果是永久的
分布式事務:
oracle使用了一個協議,叫2pc協議(兩階段提交two-phase commit),如果同時修改多個數據庫,那么其中一個數據庫(比如數據庫1)會成為事務的發起者和協調者,具體操作如下:
1 數據庫1會詢問其他所有數據庫的事務是否已經準備完畢了
2 數據庫2和數據庫3分別報告說已經ok了
3 數據庫1會廣播一條信息,讓所有數據庫都知道其他數據庫的事務已經ok了,可以提交自己的事務了
如果有一個數據庫報告的是no,那么事務1會發出消息,讓所有事務回滾
如果在數據庫2和3都返回ok的時候,數據庫1馬上要廣播給其他數據庫,結果發生掉電等問題了,那么數據庫2和數據庫3的事務都會掛起等待事務1的消息,此時就會出現可疑事務,這種事務就需要人工處理了。