Oralce中,DDL語句為什麼不能回滾

2021-05-22 17:20:21 字數 1827 閱讀 3548

在itpub上看到有人提出了這個問題。在sqlserver或一些其他的資料庫中,ddl語句也是可以回滾的,那麼oracle為什麼不能回滾ddl語句呢。

這個問題來自:http://www.itpub.net/thread-1300088-1-5.html

要說明這個問題,首先需要說明什麼是ddl語句。ddl語句是資料定義語句,包括各種資料物件的建立、修改和刪除,以及授權等操作。

在oracle中ddl語句將轉化為修改資料字典表的dml語句。乙個簡單的修改表的ddl語句,會導致oracle在後台通過遞迴sql語句進行大量的查詢和修改的操作。

如果有興趣,可以通過sql_trace根據一下ddl語句,檢查一下oracle後台實際執行了哪些操作。

在oracle中,oracle執行ddl前會發出乙個commit語句,然後執行ddl操作,最後再發出乙個commit操作。

前面提到了對於oracle而言,ddl實際上是資料字典表的一系列的修改,也就是資料字典表的dml操作,那麼理論上講oracle是完全有能力實現ddl語句的回滾的,那麼oracle為什麼設計成現在的工作方式。要知道oracle以靈活和強大的可定製性著稱,但是oracle沒有給使用者任何回滾ddl的可能性,顯示是存在著十分充分的理由。

首先分析一下oracle為什麼要在ddl語句之前和之後各執行一次commit,其實道理很簡單,oracle是為了將使用者的讀寫操作和資料字典的修改隔離開,使用者資料的讀寫不應該和資料字典的操作放在同乙個事務中。

為了說明oracle為什麼不回滾ddl語句,下面假設oracle可以回滾ddl語句,看看這會給oracle資料庫帶來什麼影響。

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

那麼ddl就要滿足read commit隔離機制,也就是說,使用者執行的ddl語句在提交前,其他使用者是無法看到的。比如a使用者執行create table t的語句,然後對t執行了一些dml。而這時其他會話是無法看到t表的。

那麼考慮這樣的情況,存在表t,包含兩個列,乙個id列,乙個created列。 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認為得不償失。其他資料庫之所以可以實現,是因為這些資料庫的鎖機制本身就存在一定缺陷,比如大量的鎖會占用系統的資源、讀寫操作互相阻塞、行級鎖可能自動公升級為表級鎖。由於已經存在這些問題,所以實現ddl的回滾並不會在很大程度上使得併發性惡化,因為即使ddl不將行鎖公升級為表鎖,可能其他的因素也會導致這種情況的發生。

DDL語句為什麼不能回滾

在itpub上看到有人提出了這個問題。在sqlserver或一些其他的資料庫中,ddl語句也是可以回滾的,那麼oracle為什麼不能回滾ddl語句呢。這個問題來自 要說明這個問題,首先需要說明什麼是ddl語句。ddl語句是資料定義語句,包括各種資料物件的建立 修改和刪除,以及授權等操作。在oracl...

Oracle中的DDL語句

ddl語言是 建立與管理表 的語句。1 建立表 建立表的語法 create table 表名 列名 資料型別 尺寸 例如 sql create table tablename column name1 number 2 column name2 varchar2 4 table created 注 ...

SQLDataSet中執行DDL語句

在sqldataset中執行我們輸入的ddl語句,並觀察執行結果。這裡為了省輸入的時間,從先輸好的記事本中複製的sql語句。效果圖 具體操作 dbgrid1.datasource datasource1.dataset clientdataset1.providername datasetprovi...