DDL語句為什麼不能回滾

2021-06-05 10:42:38 字數 1818 閱讀 5905

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

這個問題來自:

要說明這個問題,首先需要說明什麼是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不將行鎖公升級為表鎖,可能其他的因素也會導致這種情況的發生。

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

在itpub上看到有人提出了這個問題。在sqlserver或一些其他的資料庫中,ddl語句也是可以回滾的,那麼oracle為什麼不能回滾ddl語句呢。這個問題來自 http www.itpub.net thread 1300088 1 5.html 要說明這個問題,首先需要說明什麼是ddl語句。dd...

oracle中ddl不能回滾的問題

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

Hibernate事務不能回滾

今天的雨真tm大啊,嚇屎我了。工作之餘把hibernate複習了一下,乙個下午都沒有把事務搞定,然後是各種查資料,就差把hibernate官方文件再看一遍了。看到一篇文章猶如春風化雨,蜜糖潤喉一直以來都是用oracle資料庫,今天用的是mysql,未曾想到mysql這麼操蛋,還有表型別這一說,不是所...