回覆列表
  • 1 # 使用者2458114238191884

    在Oracle中DDL語句將轉化為修改資料字典表的DML語句。一個簡單的修改表的DDL語句,會導致Oracle在後臺透過遞迴SQL語句進行大量的查詢和修改的操作。

    在Oracle中,Oracle執行DDL前會發出一個COMMIT語句,然後執行DDL操作,最後再發出一個COMMIT操作。

    從現在開始,假設DDL並不會自動提交,而是事務中的一部分。

    那麼DDL就要滿足READ COMMIT隔離機制,也就是說,使用者執行的DDL語句在提交前,其他使用者是無法看到的。比如A使用者執行CREATE TABLE T的語句,然後對T執行了一些DML。而這時其他會話是無法看到T表的。

    A會話執行了ALTER TABLE T MODIFY CREATED DEFAULT SYSDATE NOT NULL,然後對T表進行了一些插入,但是沒有提交。

    這時B會話嘗試插入T表,如果DDL語句不是事務的一部分,那麼B的插入和A會話的插入之間沒有衝突,但是現在情況不同,由於A執行了T表的修改,為CREATED列增加了預設值並設定為NOT NULL,而且這個修改B會話當前是看不到的,因為A並沒有提交修改。這時如果B會話的插入沒有提供CREATED列的值,則插入操作將被鎖定。對於B而言,表結構中CREATED列仍然是可空的,因此允許插入CREATED列為空的記錄,但是由於A已經設定T的CREATED列非空,且包含預設值,因此B的插入必須被鎖定,否則如果A和B全部提交,A會話會發現即使執行了DDL語句,T表中仍然存在CREATED為空的記錄。Oracle為了實現DDL可以回滾的功能,且實現多版本讀一致性,那麼就必須在DDL發生後,將修改的表鎖定,避免其他會話的訪問造成不一致。這會導致Oracle中出現鎖升級的情況,並且嚴重的影響Oracle的併發性,而且會大大增加死鎖產生的機率。

    也許有人奇怪SQLSERVER或一些其他的資料庫為什麼可以實現DDL語句的回滾。事實上,前面提到了Oracle也是有能力實現DDL回滾的,只是這會極大的影響Oracle的併發性。要知道,Oracle的鎖機制和多版本讀一致性使得Oracle的併發性在所有資料庫產品中首屈一指。顯然為了實現DDL的回滾而損失最值得稱道的併發性,Oracle認為得不償失。其他資料庫之所以可以實現,是因為這些資料庫的鎖機制本身就存在一定缺陷,比如大量的鎖會佔用系統的資源、讀寫操作互相阻塞、行級鎖可能自動升級為表級鎖。

  • 中秋節和大豐收的關聯?
  • 怎樣做蓮藕香菇肉蒸包?