數據一致性和併發性

包含下列主題:

u 多用戶環境中的數據併發性和一致性介紹

u Oracle如何管理數據併發性和一致性

u Oracle如何鎖定數據

u Oracle閃回查詢概述

多用戶環境中數據併發性和一致性介紹

在單用戶數據庫中,用戶修改數據庫中的數據,不用擔心其他用戶同時修改相同的數據。但是,在多用戶數據庫中,同時執行的多個事務中的語句可以修改同一數據。同時執行的事務需要產生有意義的和一致性的結果。因而,在多用戶數據庫中,數據併發性和數據一致性的控制非常重要:

u 數據併發性:指很多用戶可以同時訪問數據

u 數據一致性:指每個用戶可以看到數據的一致性結果,包括自身事務和其他事務產生的改變。

爲給同時運行的事務描述一致性事務行爲,Oracle研究員定義了一個事務隔離級別:串行性(serializability)。事務行爲的的可串行模式試圖確保事務運行的方式看起來像是一次運行一個事務(或者串行性),而不是併發運行。

雖然事務間的這種隔離級別經常使用,但這種模式下的很多應用程序會降低吞吐量。併發運行事務的完全隔離意味着一個事務不能對另外一個事務正在查詢的表執行插入。簡而言之,真實環境中經常要在優秀的事務隔離級別和性能之間做一個折衷。

Oracle提供了兩個隔離級別,爲應用程序開發人員提供可選的模式來兼顧性能和一致性。

可預防現象和事務隔離級別

ANSI/IOS SQL標準(SQL 92)定義了4個事務隔離級別,對事務處理性能的影響也個不相同。這些隔離級別是考慮了事務併發執行必須避免的3個現象提出的。

3個應該避免的現象爲:

u 髒讀:一個事務可以讀取其他事務寫入但還沒有提交的數據。

u 不可重複讀(模糊讀):一個事務重複讀到以前讀到的和查詢到的數據,這些數據是其他的已提交事務已經修改或者刪除的數據。

u 幻影讀:一個事務重複運行查詢返回的一些列行,這些行包括其他已經提交的事務已經插入的額外的行。

SQL92根據這些對象定義了4個隔離級別,事務運行在特定的隔離級別允許特別的一些表現。如表13-1所示。

表13-1 隔離級別阻止的讀現象

隔離級別

髒讀

不可重複讀

幻影讀

非提交讀(read uncommitted)

允許

允許

允許

提交讀(read committed)

不允許

允許

允許

重複讀(Repeatable read)

不允許

不允許

允許

串行性(serializable)

不允許

不允許

不允許

Oracle提供提交讀(read commited)和串行性(serializable)隔離級別,而只讀模式不是SQL92的一部分。提交讀是默認的。

鎖機制概述

通常來說,多用戶數據庫使用多種類型的數據鎖來解決相關數據併發、一致性和完整性的問題。鎖是防止訪問同一資源的事務的破壞性干擾的一種機制。

資源包括兩種通用的類型:

u 用戶對象,例如表、行(結構和數據)

u 用戶不可見的系統對象,比如內存中的共享數據結構和數據字典行

Oracle如何管理數據併發性和一致性

Oracle在一個多用戶環境中維護數據一致性,是通過使用多版本一致性模型和不同類型的鎖和事務來做到的。這一部分包含下列主題:

u 多版本併發控制

u 語句級別讀一致性

u 事務級別讀一致性

u 真正應用集羣的讀一致性

u Oracle隔離級別

u 提交讀和串行性隔離級別的比較

u 隔離級別的選項

多版本併發控制

Oracle自動爲一個查詢提供讀一致性,就是說查詢結果來源於一個單個的時間點(語句級別讀一致性)。Oracle還爲事務中所有的查詢提供讀一致性(事務級別讀一致性)。

Oracle使用回滾段中維護的信息來提供這些一致性視圖。回滾段包含未提交的事務或最近提交的事務修改的數據的原始值。圖13-1顯示了Oracle如何通過回滾段中的數據提供語句級別的讀一致性。

圖13-1 讀一致性和事務

當一個查詢進入執行階段,就確定了當前系統修改號(SCN)。在圖13-1中,系統修改號爲10023。在查詢讀取數據塊時,只有對寫入SCN號可見的塊纔會使用。塊中的修改數據(更近的SCN)從回滾段中重新構建數據,這些重構數據返回給查詢。因而,每個查詢返回查詢開始的時間的SCN涉及的所有提交數據。在查詢執行時其他事務造成的修改不被採用,確保每個查詢返回的都是一致性數據。

語句級別讀一致性

Oracle總是執行語句級別讀一致性。這可以確保單個查詢返回的所有數據來源於單個時間點(查詢開始的時間點)。因而,一個查詢看不到髒數據或者查詢執行期間其他事務提交的任何改變。查詢執行開始後,只有查詢開始之前提交的數據可以被查詢到。查詢不能看到語句開始執行之後提交的任何數據。

Oracle自動爲每個查詢提供一致性結果,確保數據一致性,而不需要用戶參與。包含子查詢的SELECT、INSERT子句,UPDATE和DELETE所有查詢數據,不管是顯式的還是隱式的SQL語句都返回一致性數據。這些語句使用一個查詢來確定要影響哪些數據(SELECT、INSERT、UPDATE或者DELETE)。

一個SELECT語句是一個顯式的查詢,可以包含嵌套查詢或者關聯操作符。一個INSERT語句可以使用嵌套查詢。UPDATE和DELETE語句可以使用WHERE子句或者子查詢來隻影響表中的一些行。

使用INSERT、UPDATE或者DELETE語句確保一系列一致性的結果。但是,他們並不能看到本身DML語句所做的改變。換句話說,這些操作的查詢只能看到這些操作發生改變之前的數據。

注意:如果一個SELECT列表包含一個函數,那麼數據庫在運行PL/SQL函數代碼中SQL的語句級別提供語句級別讀一致性,而不是父級別。例如,一個函數可以訪問另一個用戶已經修改和提交的表數據。對於函數中的每個SELECT執行,都會創建一個新的讀一致性快照。

事務級別讀一致性

Oracle還提供事務級別讀一致性選項。當一個事務運行在串行性(serializable)摸式下,所有的數據訪問反映的數據庫狀態是事務開始的時間。這意味着同一個事務中所有查詢看到的數據都和一個時間點保持一致,當然這個事務本身所做的改變自己可以看到。事務級別的讀一致性會產生重複讀,但不會產生幻影讀。

真正應用集羣的讀一致性

真正應用集羣(RAC)使用cache到cache的塊傳輸機制(cache融合)來從一個實例到另一個實例傳輸塊的讀一致映像。RAC使用高速度、低等待時間的互聯方式完成傳輸,滿足遠程對數據塊的請求。

Oracle隔離級別

Oracle提供了3種隔離級別:

隔離級別

描述

提交讀(read commited)

這是默認的事務隔離級別。事務中每個執行的查詢只能看到查詢(不是事務)開始之前提交的數據。Oracle查詢不會讀取髒(沒有提交的)數據。

因爲Oracle不阻止其他事務通過查詢修改本事務讀取的數據,這個數據可以在本事務的兩個查詢之間由其他事務修改。因而,一個事務中運行給定的查詢兩次會出現幻影讀和不可重複讀現象。

串行性(Serializable)

串行性事務只能看到事務開始時提交的修改,和本事務通過INSERT、UPDATE和DELETE語句修改的數據。串行性事務不會出現不可重複讀或幻影讀。

只讀(read-only)

只讀事務只能看到事務開始時提交的修改,不允許執行INSERT、UPDATE、DELETE語句。

設置隔離級別

應用程序設計人員、應用程序開發人員和數據庫管理員可以根據應用程序和負載情況來爲不同的事務選擇合適的隔離級別。你可以在事務開始時通過使用下列語句來設置事務隔離級別。

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

SET TRANSACTION READ ONLY;

在每個事務開始用SET TRANSACTION語句設置隔離級別,會增加網絡和處理負擔,也可以使用ALTER SESSION語句來爲所有以後的事務設定隔離級別:

ALTER SESSION SET ISOLATION_LEVEL SERIALIZABLE;

ALTER SESSION SET ISOLATION_LEVEL READ COMMITTED;

提交讀隔離級別

Oracle默認隔離級別是提交讀。這個隔離級別對於事務很少衝突的環境是合適的。Oracle讓每個查詢根據它自己的實體化視圖時間運行,因而允許不可重複讀和多次執行一個查詢導致的幻影讀,但會提供很高的性能。提交讀隔離級別是事務很少衝突的環境的合適的隔離級別。

串行性隔離級別

串行性隔離級別適合如下環境:

u 大數據庫中存在影響少量行的小事務的情況下

u 兩個並行事務很少修改同一行的情況下

u 相對較長時間運行的事務主要是隻讀的

串行性隔離級別允許並行事務只能修改那些他們可以修改的部分,就如同事務被調度依次運行一樣。明確來說,Oracle只有確定串行性事務開始時,其他事務修改一個行的修改已經提交,纔會允許在這個數據行上使用串行性事務。

爲加快這個規則的效率,Oracle在數據塊上保留控制信息,顯示了塊中哪些行包含提交的和未提交的數據。某種程度上來說,塊包含最近影響塊上每一行的事務的歷史。可以保留的歷史由CREATE TABLE和ALTER TABLE語句的INITRANS參數來控制。

在某些情況下,Oracle沒有足夠的歷史信息來確定是否一行被最近的事務修改過。當很多事務併發的修改同一個數據塊或者在很短的時間發生會出現這種情況(沒有足夠的空間記錄歷史)。如果一個表經常被很多事務修改同一個塊,你可以通過對錶的INITRANS設置很高的值來避免這種情況(沒有足夠的空間記錄歷史)。這使得Oracle在每個塊中分配足夠的空間來記錄最近訪問塊的事務的歷史。

如果串行性事務試圖修改和刪除其他在本事務開始之後的其他事務提交的數據,會產生一個錯誤:

ORA-08177: Cannot serialize access for this transaction

當串行性事務因爲Cannot serialize access錯誤而失敗時,應用程序可以採取下列措施:

u 提交這個時間點執行的工作

u 執行另外(但是不同)的語句(可能回滾到事務早期構建的保存點)

u 撤銷整個事務

圖13-2 顯示了Cannot serialize acess錯誤導致的失敗時,一個應用程序回滾和重試事務的例子:

圖13-2 串行性事務失敗

提交讀和串行性隔離級別的比較

Oracle爲應用開發人員提供了兩種不同規格的隔離級別的選項。提交讀和串行性隔離級別都提供很高級別的一致性和併發性。兩個級別都爲降低競爭而提供了讀一致性多版本併發性控制模型和行級互斥鎖的實現,並且都是爲真實世界的應用部署設計的。

事務系列一致性

在Oracle中查看提交讀和串行性隔離級別的一個很有用的辦法是考慮下列場景:假定你有一系列數據庫表(或者任何系列數據),這些表的一個特定順序的行讀,在任何特定時間提交的一系列事務。一個操作(查詢或者事務)如果它的所有數據讀是同一系列的提交事務寫入的,那麼這個操作是事務系列一致性的。如果它的數據讀一部分由一系列事務影響,一部分由另一系列事務影響,那麼它就不是事務系列一致性的。操作是否事務系列一致性實際上看是數據庫所處狀態是否反映了單個系列的提交事務。

Oracle爲提交讀模式的事務執行的每個語句提供事務系列一致性。串行性模式歲每個事務提供事務系列一致性。

圖13-2彙總了Oracle中提交讀和串行性事務的主要不同。

圖 13-2 提交讀和串行性事務

提交讀

串行性

髒寫(dirty write)

不允許

不允許

髒讀(dirty read)

不允許

不允許

不可重複讀(Nonrepeatable read)

允許

不允許

幻影讀(Phantoms)

允許

不允許

遵從ANSI/ISO SQL 92

讀取實體化視圖時間

語句

事務

事務系列一致性

語句級別

事務級別

行級別鎖

讀阻塞寫

寫阻塞讀

不同行寫入阻塞寫入

同一行寫入阻塞寫入

等待鎖定事務

導致cannot serialize access錯誤

鎖定事務結束產生錯誤

鎖定事務提交產生錯誤

行級別鎖

提交讀和串行性事務都使用行級鎖,都會在試圖修改一個沒有提交的並行事務更新的行時產生等待。第二個事務事務等待其他事務提交或者撤銷來釋放它的鎖,才能更新給定的行。如果其他事務回滾了,不管等待的事務是什麼隔離級別,都可以對以前鎖定的行進行修改,就好像其他事務不存在一樣。

但是,如果其他事務提交併釋放了它的鎖,提交讀事務可以執行它想要的修改。一個串行性事務會產生一個Cannot serialize access錯誤而失敗,因爲其他事務提交的修改是串行性事務開始之後的事情了。

引用完整性

因爲Oracle在讀一致性或串行性事務不使用讀鎖,一個事務讀取的數據可以被另外一個覆蓋。在應用級別執行數據完整性檢查的事務不能假設他們讀取的數據在事務執行期間保持不變,即使這些改變對事務不可見也不行。即使在串行性事務的情況下,如果應用級別的一致性檢查如果不用心編寫,也會導致數據庫不一致。

注意:你可以在真正應用集羣中使用提交讀和串行性事務隔離級別。

分佈式事務

在分佈式數據庫環境中,給定事務在多個物理數據庫中更新數據的通過兩步提交確保所有的節點都提交或者都沒有提交。在這樣的環境中,參加串行性事務的所有的服務器,不論是Oracle還是非Oracle,都要求支持串行性模式。

如果串行性事務試圖在一個不支持串行性事務的服務器的數據庫的數據,事務會返回一個錯誤。事務會撤銷,只有在遠程服務器支持串行性事務時才進行新的嘗試。

相比之下,讀一致性事務可以在不支持串行性事務的服務器之間執行分佈式事務。

隔離級別選項

應用程序設計人員和開發人員需要依據應用程序性能、一致性需求和應用程序編碼需求而選擇一個隔離級別。

在多併發用戶快速提交事務的環境中,設計人員必須基於期望的事務發生率和需要的迴應時間來評估事務性能。對於大多數高性能環境來說,隔離級別的選擇會在併發性和一致性之間做一個平衡。

檢查數據庫一致性的應用程序邏輯必須考慮一個事實:任何模式下讀不阻塞寫。

Oracle隔離級別通過行級別鎖和Oracle多版本併發控制系統提供了高水平的一致性、併發性和性能。Oracle中讀寫互相不阻塞。因而,雖然查詢仍然看到一致性數據,不需要讀取未提交數據,但是提交讀和串行性隔離提供了高水平的高性能的併發。

Oracle提交讀隔離級別爲每個查詢提供事務系列一致性。就是說,每個查詢看到的數據是一致性狀態的。因而,讀一致性隔離級別可以滿足大部分應用程序,如果在其他沒有使用多版本併發控制的數據庫管理系統上,類似程序可能需要更高的隔離級別。

提交讀隔離模式並不會讓應用程序陷入Cannot serialize access錯誤並循環重新開始一個事務。在大多數應用程序中,事務很少需要重複發佈同一個查詢,所以對於大部分應用程序來說,避免幻影讀和不可重複讀並不重要。因而很多開發人員選擇提交讀模式來避免在每個事務中編寫這樣的錯誤檢查和重試代碼。

串行性隔離級別

Oracle串行性隔離級別適合於兩個併發事務很少修改同一行和長時間運行的事務主要是隻讀的環境。它還適合大型數據庫且只更新少量行的短事務的環境。

串行性隔離模式某種程度上通過避免不可重複讀和幻影讀來提供了更多的一致性,如果在一個讀寫事務中存在一個執行多次的查詢,串行性隔離模式非常重要。

和其他串行性隔離的實現不同,這些實現將讀和寫一樣鎖定。Oracle提供了非鎖定查詢和行級別鎖的良好的顆粒度,上述兩點降低了讀寫的爭用。對於發生大量讀寫爭用的應用來說,Oracle串行性隔離比其他系統可以提供更高的吞吐量。因而,適合Oracle串行性的應用程序未必適合其他系統。

Oracle串行性事務的所有查詢將數據庫整個作爲一個時間點,所以這個隔離級別適合在讀/寫事務中發佈多個一致性查詢。一個包含寫入功能的報表應用程序指的是彙總數據並保存在數據庫中,這樣的程序可以使用串行性模式,因爲它提供了READ ONLY事務提供的一致性,還允許INSERT、DELETE和UPDATE。

注意:事務中的DML語句包含子查詢應該使用串行性隔離來確保一致性讀。

編寫串行性事務需要額外的工作,應用程序開發人員需要檢查Cannot serialize acess錯誤並且撤銷或重試事務。類似的額外代碼在其他數據庫管理系統中是用來管理死鎖的。爲適應公用標準或在多個數據庫管理系統中運行的應用程序,可能需要爲串行模式事務單獨設計。檢查串行性失敗和重啓的事務應該使用提交讀模式,這樣就不會產生串行性錯誤。

串行性模式在相對較長事務更新的行和大量短更新事務訪問的行一樣時並不適合。因爲長時間運行的事務未必是給定行的第一個更新,它需要重複回滾,浪費一些工作。注意,串行性模式的通常的讀鎖、悲觀鎖實在這種環境中也不適合,因爲長時間運行的事務,即使是讀鎖,也會阻塞短更新事務的進度,反過來也是如此。

在使用串行性模式時,應用開發人員需要考慮事務回滾和重試的開銷。在讀鎖環境中,死鎖經常發生,使用串行性模式需要通過結束事務來回滾工作,然後重試。在一個高爭用的環境中,這種操作會佔用大量資源。

在大部分環境中,一個接收到Cannot serialize access錯誤而重啓的事務未必會遇到另一個衝突的事務。出於這個原因,這些語句在串行性事務中儘早和其他事務競爭會比較有幫助。但是,並不能保證事務可以成功完成,所以應用程序應該編碼來限制重試的次數。

雖然Oracle串行性模式是兼容SQL92,並且和讀鎖實現比較還提供很多優勢,但是它不能對那樣的系統提供語法上的標識。應用設計人員必須考慮這樣的事實:Oracle並不像其他系統一樣讀阻塞寫。在應用程序級別檢查數據庫一致性的事務需要使用代碼:SELECT FOR UPDATE。在其他使用串行性模式的事務的環境移植到Oracle可以考慮使用這個語句。

靜默數據庫

你可以將系統設置爲靜默數據庫。處於靜默狀態的系統沒有活動的會話,除非是用戶SYS和SYSTEM。一個活動事務是指會話中包含一個事務、一個查詢、一個數據獲取或者一個PL/SQL過程,或者當前持有任何共享資源的會話(例如:隊列共享着一些串行訪問數據庫資源的內存結構,且和一個會話或事務關聯)。數據庫管理員是僅有的可以在系統處於靜默狀態還可以操作的用戶。

數據庫管理員可以在靜默狀態執行一個特定的操作,這些操作在非靜默狀態可能是不安全的。這些動作包括:

u 如果存在併發用戶事務或查詢可能失敗的動作。例如,如果一個併發事務訪問的表的模式無法修改

u 動作的中間結果對於用戶併發事務或查詢可能有害。例如,假設有一個大表T和一個PL/SQL包在上面操作。你可以將表T分成兩個表T1和T2,修改PL/SQL包來引用信標T1和T2,而不是舊錶T。

當數據庫處於靜默狀態,你可以這樣做:

CREATE TABLE T1 AS SELECT ... FROM T;

CREATE TABLE T2 AS SELECT ... FROM T;

DROP TABLE T;

然後你可以刪除舊的PL/SQL包,重新創建它。

對哪些必須持續工作的系統來說,不需要關閉數據庫就能夠執行這樣動作的能力是很重要的。

數據庫資源管理器在系統靜默狀態時阻塞了除SYS和SYSTEM的所有新用戶。這些動作在系統返回正常狀態(非靜默)時可以執行。用戶不會從靜默狀態獲得任何額外的錯誤信息。

數據庫如果設定爲靜默

數據庫管理員使用ALTER SYSTEM QUIESCE RESTRICTED語句來靜默數據庫。只有用戶SYS和SYSTEM才能發佈ALTER SYSTEM QUIESCE RESTRICTED語句。對於數據庫開放狀態的所有實例,發佈這個語句有如下影響:

u Oracle指示所有實例中的數據庫資源管理器阻止所有除SYS和SYSTEM用戶之外的所有非活動會話變爲活動會話。除SYS和SYSTEM之外的用戶無法啓動一個新會話、新事務、新查詢、新的數據獲取或者新的PL/SQL操作。

u Oracle等待所有實例中的非SYS或SYSTEM的用戶所有現存事務完成(提交或者結束)。Oracle還等待所有非SYS或SYSTEM的用戶運行的不在事務中的查詢、數據獲取和PL/SQL過程完成。如果查詢由多個連續的OCI獲取執行,Oracle並不等待所有的獲取結束。它等待當前的獲取結束,阻塞新的數據獲取。Oracle還等待所有持有任何共享資源(比如隊列)的所有會話(非SYS或者SYSTEM)釋放這些資源。這些操作完成之後,Oracle將數據庫置入靜默狀態,完成QUIESCE RESTRICTED語句的執行。

u 如果實例運行在共享服務器模式,Oracle指示數據庫資源管理器來阻塞這個實例上的登陸(非SYS和SYSTEM)。如果一個實例運行在非共享服務器模式,Oracle並不對實例的登陸施加任何限制。

在靜默狀態期間,你不能修改任何實例的資源管理計劃。

ALTER SYSTEM UNQUIESCE語句將所有運行實例返回到正常狀態,所以所有阻塞動作可以繼續處理。一個管理員可以通過查詢v$blocking_quiesce視圖來確定鎖定的會話。

Oracle如何鎖定數據

鎖是一種阻止訪問同一資源的事務破壞性干擾的一種機制,資源可以是用戶對象(如表和行)或用戶不可見的系統對象(比如內存中的共享數據結構和數據字典行)。

在所有的情況下,Oracle都是在SQL語句執行時自動獲得需要的鎖,所以用戶不需要關心這些細節。Oracle自動使用最低的、適當的限制來提供高水平的數據併發,還提供數據完整性防護。Oracle還允許用戶手動鎖定數據。

事務和數據併發

Oracle在事務之間使用鎖機制來提供數據併發性和完整性。因爲Oracle的鎖機制和事務控制緊密結合,應用設計人員只需要適當定義事務,Oracle自動管理鎖。

記住Oracle鎖是完全自動的,不需要任何用戶干預。所有SQL語句執行時隱式加鎖,所以數據庫用戶不需要顯式鎖定任何資源。Oracle默認的鎖機制在數據上提供低級別的限制來確保數據完整性,還允許高水平的數據併發性。

鎖模式

Oracle在多用戶數據庫中使用兩種模式的鎖:

u 排他鎖:阻止相關資源被共享。修改數據自動獲得這個鎖模式。如果排他鎖沒有釋放,排他鎖定一個資源的第一個事務是僅有的一個可以修改該資源的事務。

u 共享鎖:允許相關資源被共享(和涉及的操作有關)。多個用戶讀取數據可以共享數據、持有共享鎖來阻止併發的寫入權限(需要排他鎖)。多個事務可以在同一個資源上獲得共享鎖。

鎖持續期

事務內語句獲得的所有鎖在事務存續期間持有,阻止併發事務的髒讀、丟失更新和破壞性的DDL操作之類的破壞性干擾。一個事務的SQL語句造成的改變,只有提交之後其他的事務才能看到。

在事務提交或者撤銷時,Oracle會釋放事務中的語句獲得的鎖。回滾到保存點時,Oracle也釋放保存點後的鎖。但是,只有事務不再等待以前鎖定的資源時,纔可以在現在可用的資源上獲得鎖。等待事務一直等待,除非原始事務完全提交或者回滾之後。

數據鎖轉換和鎖升級

一個事務持有事務內插入、更新、刪除行的排他鎖。因爲行鎖是在最高級別的限制上獲得,不需要執行鎖轉換。

Oracle根據需要自動將低限制的表鎖轉換爲一個高限制的鎖。例如,假定一個事務使用了包含FOR UPDATE子句的SELECT語句來鎖定了表的行。因而,它獲得了表的排他行鎖和行共享表鎖。如果事務後來更新了一個或多個鎖行,共享表鎖的行自動轉換爲一個排他表鎖的行。

在大量同一級別的顆粒(如行)擁有鎖時,一個數據庫將鎖升級爲高水平的顆粒(如表),這個叫做鎖升級。例如,如果一個用戶鎖定了一個表很多行,某些數據庫自動逐步將用戶行鎖升級到單個表。鎖的數量減少了,但是鎖定的限制行增加了。

Oracle不會升級鎖。升級鎖大大的增加了死鎖的可能性。想象一種情況,系統試圖在事務T1中升級鎖,但是因爲事務T2持有鎖,而無法獲得。如果事務T2也對同樣的數據需要升級鎖,就會發生死鎖。

死鎖

在兩個或者更多的客戶等待彼此的數據鎖時就會發生死鎖。死鎖阻止了某些事務繼續工作。圖13-3是一個死鎖中兩個事務的假想說明。

在圖 13-3中,A點沒有任何問題,因爲每個事務都持有它視圖更新的行的鎖。每個事務不需要中斷就可以處理。但是,每個事務都視圖更新當前被其他事務持有的行。因而,死鎖在B點發生,因爲沒有事務可以獲得它執行或者結束的需要的資源。這是一個死鎖,因爲無論每個事務等待多久,衝突鎖還是不釋放。

圖13-3 死鎖中兩個事務

死鎖檢測

Oracle自動檢測死鎖情況,並通過回滾死鎖中包含的一個語句來解決死鎖,從而釋放一系列衝突的行鎖。遭受語句級別回滾的事務會返回對應的消息。回滾的語句屬於檢測到死鎖的事務。通常,被告知的事務應該顯式回滾,但也可以等待之後重試回滾語句。

注意:在分佈式事務中,本地死鎖通過分析等待數據檢測,全局死鎖通過超時來檢測。檢測之後,分佈式死鎖和非分佈式死鎖的數據庫和應用處理方式相同。

死鎖通常是事務顯式的覆蓋Oracle的默認鎖時發生。因爲Oracle本身沒有鎖升級,查詢也不使用讀鎖,只使用行鎖(而不是頁鎖),在Oracle中很少發生死鎖。

避免死鎖

如果訪問同樣表的事務按照同樣的順序鎖定這些表,不管通過顯式的還是隱式的,多數死鎖都可以避免的。例如,所有的應用開發人員可以遵循下列規則:主表和子表都需要更新時,先鎖定主表,再鎖定子表。如果這類規則嚴格指定,所有應用程序都遵守,死鎖就很少會發生。

當你要爲一個事務請求一系列鎖,考慮首先獲得最排他的鎖(兼容性最好)。

鎖類型

Oracle自動使用不同類型的鎖來控制數據的併發訪問,阻止用戶之間的破壞性干擾。Oracle自動爲事務鎖定一個資源,阻止其他需要同一資源的共享鎖的事務獲得鎖。在某些條件下,事務不再需要資源時,Oracle自動釋放鎖。

在這個操作中,Oracle自動根據資源鎖定情況和執行的操作在不同的限制級別上獲得不同類型的鎖。

Oracle鎖通常分爲3類。

描述

DML鎖(數據鎖)

DML鎖保護數據。例如,表鎖鎖定整個表,行鎖鎖定選擇行

DDL鎖(字典鎖)

DDL鎖保護模式對象的結構,例如表和視圖的定義

內部鎖和閂

內部鎖和閂保護內部數據庫結構,比如數據文件。內部鎖和閂是完全自動的

下面開始討論DML鎖、DDL鎖和內部鎖。

DML

DML鎖(數據鎖)的目的是確保多個用戶併發訪問的數據的完整性。DML鎖阻止了同時發生的衝突的DML或者DDL操作造成的破壞性干擾。DML語句自動獲得行級鎖和表級鎖。

注意:每類鎖或鎖類型後面括號裏的縮寫詞是在企業管理器的鎖監視器使用的縮略詞。企業管理器可能用TM顯示任何表鎖,而不是顯示錶鎖的類型(如RS或SRX)。

行鎖(TX)

行級鎖主要用於阻止兩個事務同時修改一行。當事務需要修改一行時,需要獲得一個行級鎖。

一個語句或者事務可以持有行鎖的數目並沒有限制,Oracle並不會將行級鎖升級爲粗粒度的鎖。行鎖提供了最好的顆粒度和最好的併發性和吞吐量。

多版本併發控制和行級別鎖定結合意味着只有用戶訪問同一行的數據時纔會產生競爭,具體如下:

u 讀數據不需要等待同一行的寫入

u 寫入數據不需要等待同一行數據的讀取,除非使用了SELECT .... FOR UPDATE語句,這個語句明確的請求了讀鎖。

u 寫入只在其他寫入試圖同時更新同一行數據時纔會等待

注意:讀數據可能在某些特殊情況下(分佈式事務中)等待同一數據塊的寫入。

一個事務通過下列語句修改的每行都會獲得一個行級互斥鎖:INSERT、UPDATE、DELETE和SELECT ... FOR UPDATE。

行修改總是排他鎖,所以其他的事務無法修改這一行,除非持有鎖的事務提交或者回滾了。但是,如果事務由於實例失敗而死掉,塊級別的恢復會在整個事務恢復之前使行可用。Oracle上述語句的情況下自動獲得行級鎖。

如果一個事務在一行上獲得一個行鎖,事務也在對應表上獲得一個表鎖。這個表鎖阻止了衝突的DDL操作,這個DDL操作可能覆蓋當前事務中的數據修改。

表鎖(TM)

表級鎖主要用於併發控制併發的DDL操作,比如阻止在一個DML操作過程中刪除相關表。當在一個表上執行DDL或DML語句,就獲得一個表鎖。表鎖不影響DML操作的並行性。對於分區表,表鎖在表和子分區級別上都可以獲得。

一個事務在一個表使用下列DML語句:INSERT、UPDATE、DELETE、SELECT....FOR UPDATE和LOCK TABLE時獲得一個表鎖。這些DML操作獲得表鎖有兩個目的:爲事務保留表的DML訪問權限和阻止和這個事務衝突的DDL操作。任何表鎖都阻止了同一個表上的排他DDL鎖的獲得,從而阻止了需要這個鎖的DDL操作。例如,如果一個沒有提交的事務持有一個表的表鎖,表不能修改結構和刪除。

表鎖可以以多種方式持有:行共享(row share,RS)、行排他(row exclusive,RX)、共享行排他(share row exclusive,SRX)、和排他鎖(exclusive,X)。一個表的鎖模式的限制確定了同一表上可以獲得和持有的其他表鎖。

表 13-3顯示了語句獲得表鎖模式和這表鎖允許和禁止的操作。

表 13-3 表鎖的彙總

SQL語句

表鎖模式

是否允許下列鎖類型

RS

RX

S

SRX

X

SELECT ..... FROM table

None

Y

Y

Y

Y

Y

INSERT INTO table ....

RX

Y

Y

N

N

N

UPDATE table ....

RX

Y*

Y*

N

N

N

DELETE FROM table .....

RX

Y*

Y*

N

N

N

SELECT .... FROM table FOR UPDATE OF ...

RS

Y*

Y*

Y*

Y*

N

LOCK TABLE table IN ROW SHARE MODE

RS

Y

Y

Y

Y

N

LOCK TABLE table in ROW EXCLUSIVE MODE

RX

Y

Y

N

N

N

LOCK TABLE table in SHARE MODE

S

Y

N

Y

N

N

LOCK TABLE table in SHARE RWO EXCLUSIVE MODE

SRX

Y

N

N

N

N

LOCK TABLE table in EXCLUSIVE MODE

X

N

N

N

N

N

RS:行共享鎖

RX:行排他鎖

S:共享鎖

SRX:共享行排他鎖

X:排他鎖

*:如果沒有其他事務持有衝突的行鎖就爲是,否則發生等待。

下面開始說明表鎖的每個模式,從最少限制到最多限制。還描述了在那個模式下導致事務獲得表鎖的動作和這種鎖模式下其他事務允許和禁止的動作。

行級共享表鎖(RS)

行級共享表鎖(有時候也叫部分共享表鎖)指出持有表上鎖的事務已經在表上鎖定了行,要更新他們。一個行級表共享鎖在下列SQL語句運行時自動獲得:

SELECT .... FROM table .... FOR UPDATE OF .....;

LOCK TABLE table IN ROW SHARE MODE;

行級共享表鎖是最少限制的表鎖,爲表提供最高水平的併發性。

允許的操作:持有行共享表鎖的事務允許其他事務併發的在同一表上執行查詢、插入、更新、刪除或者鎖定行。因而,其他事務可以在同一個表上同時獲得行共享、行排他、共享、共享行排他表鎖。

禁止的操作:持有行共享表鎖的事務阻止其他事務使用下面的語句使用排他寫訪問同一個表:

LOCK TABLE table IN EXCLUSIVE MODE;

行排他表鎖(RX)

一個行排他表鎖(也叫做部分排他表鎖,SX)通常顯示持有鎖的事務已經在表上更新了一行或多行。一個行排他表鎖在使用下列語句修改表時自動獲得:

INSERT INTO table ....;

UPDATE table ...;

DELETE FROM table ....;

LOCK TABLE table in ROW EXCLUSIVE MODE;

行排他表鎖比行共享表鎖的限制多一些。

允許的操作:一個事務持有的行排他表鎖允許其他事務在同一個表上併發的查詢、插入、更新、刪除或鎖定行。因而,行排他表鎖允許多個事務在一個表上同時擁有表排他鎖和表共享鎖。

禁止的操作:一個事務持有的行排他表鎖阻止其他事務手工鎖定表來執行讀取或寫入。因而,其他事務不能使用下面的語句併發的鎖定表:

LOCK TABLE table IN SHARE MODE; 

LOCK TABLE table IN SHARE EXCLUSIVE MODE;

LOCK TABLE table IN EXCLUSIVE MODE;

共享表鎖(S)

對錶執行下面的語句會自動或共享表鎖:

LOCK TABLE table IN SHARE MODE;

允許的操作:一個事務持有的共享表鎖允許其他事務只能查詢表、使用SELECT .... FOR UPDATE來鎖定特定行或者運行LOCK TABLE ... IN SHARE MODE語句。不允許其他事務進行任何更新。多個事務可以併發的持有同一個表的共享表鎖。在這種情況下,沒有事務可以更新表(即使一個事務使用SELECT ... FOR UPDATE語句持有行鎖也不行)。因而,一個持有共享表鎖的事務只有在沒有其他事務持有這個表的共享表鎖的情況下更新表。

禁止的操作:一個事務持有的共享表鎖阻止其他事務修改這個表和阻止執行下面的語句:

LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE;

LOCK TABLE table IN EXCLUSIVE MODE;

LOCK TABLE table IN ROW EXCLUSIVE MODE;

共享行排他表鎖(SRX)

共享行排他表鎖(也叫共享部分排他表鎖,SSX)比共享鎖限制多一些。使用下面的語句可以獲得一個共享行排他表鎖:

LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE;

允許的操作:給定一個表同時只有一個事務可以獲得共享行排他表鎖。一個事務持有的共享行排他表鎖允許其他事務查詢或者使用SELECT ... FOR UPDATE語句來鎖定特定行,但不允許更新表。

禁止的操作:一個事務持有的共享行排他表鎖阻止其他事務獲得行排他表鎖和修改這個表。還阻止其他事務獲得共享鎖、共享行排他鎖、排他表鎖,這些阻止其他事務執行下列語句:

LOCK TABLE table IN SHARE MODE;

LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE;

LOCK TABLE table IN ROW EXCLUSIVE MODE;

LOCK TABLE table IN EXCLUSIVE MODE;

排他表鎖(X)

排他表鎖是限制最多的表鎖,允許持有鎖的事務排他的寫入到表中。一個排他表鎖使用下列語句可以獲得:

LOCK TABLE table IN EXCLUSIVE MODE;

允許的操作:只有一個事務可以獲得表的排他表鎖,一個排他表鎖只允許其他事務查詢表。

禁止的操作:一個事務持有的排他表鎖禁止其他事務執行任何類型的DML操作或者阻止在表上放置任何類型的鎖。

DML語句自動獲得的鎖

前面的部分描述了不同類型的數據鎖、可以獲得那種鎖類型、什麼時候可以獲得鎖、什麼時候獲得鎖和禁止什麼操作。下面彙總了Oracle如何爲不同的DML操作自動鎖定數據。

在下面的部分,表 13-4彙總了信息。

表13-4 DML語句獲得的鎖

DML 語句

行鎖

表鎖類型

SELECT ... FROM table

INSERT INTO table ...

X

RX

UPDATE table ...

X

RX

DELETE FROM table ...

X

RX

SELECT ... FROM table ...    FOR UPDATE OF ...

X

RS

LOCK TABLE table IN ...

ROW SHARE MODE

RS

ROW EXCLUSIVE MODE

RX

SHARE MODE

S

SHARE EXCLUSIVE MODE

SRX

EXCLUSIVE MODE

X

X:排他鎖

RX:行排他鎖

RS:行共享鎖

S:共享鎖

SRX:共享行排他鎖

查詢的默認鎖

查詢是很少干擾其他SQL語句的一種語句,因爲它只讀取數據。INSERT、UPDATE和DELETE語句可以包含隱式的部分查詢語句。查詢包括下列類型的語句:

SELECT

INSERT .... SELECT ....;

UPDATE ...;

DELETE ...;

查詢不包括下列語句

SELECT ... FOR UPDATE OF ...;

不使用FOR UPDATE語句的所有查詢包含下列特徵:

u 查詢沒有任何數據鎖。因而,其他事務可以查詢和修改正在查詢的表,包括被查詢的特定行。因爲查詢沒有FOR UPDATE子句所以沒有獲得任何數據鎖來阻塞其他操作,這些查詢在Oracle中常被稱爲非阻塞查詢。

u 查詢不需要等待任何數據鎖釋放。它總是執行。(查詢在分佈式事務的情況下可能需要等待數據鎖)

INSERT、UPDATE、DELETE和SELECT ... FOR UPDATE的默認鎖

INSERT、UPDATE、DELETE和SELECT ... FOR UPDATE語句的鎖特徵如下:

u 包含DML語句的事務在語句修改的行上獲得排他行鎖。其他事務不能更新或刪除鎖定行,除非鎖定事務提交或者回滾。

u 包含DML語句的事務不需要對子查詢和WHERE子句的隱式查詢選擇的任何行加鎖。DML語句的子查詢或隱含查詢確保查詢開始的一致性,而且看不到所屬DML語句的影響。

u 事務中的查詢可以看到同一事務中前一個DML語句的改變,但不能看到事務開始之後開始的其他事務所做的修改。

u 除必須的排他行鎖外,包含一個DML語句的事務至少在包含影響行的表上獲得一個行排他表鎖。如果包含的事務已經持有一個這個表的共享鎖、共享行排他鎖或者排他表鎖,就無法獲得行排他表鎖。如果包含事務已經持有一個行共享表鎖,Oracle自動將鎖傳喚爲行排他表鎖。

DDL

正在執行的DDL操作引用和操作的模式對象使用數據字典鎖(DDL)來保護。前面說過,DDL語句隱式的提交當前事務。例如,假定用戶創建一個過程。對於用戶的單語句進程來說,Oracle自動對過程定義的所有引用的模式對象獲得DDL鎖。DDL鎖阻止了過程編譯完成之前其中的引用對象被修改結構或者刪除的操作。

Oracle自動基於任何DDL事務需要的字典鎖。用戶不能顯式的請求DDL鎖。只有在DDL操作中引用和修改的模式對象可以獲得鎖。整個數據字典從來不會鎖定。

DDL鎖分爲3類:排他DDL鎖,共享DDL鎖,可中斷解析鎖。

排他DDL鎖

大多數DDL操作(除了下面的“共享DDL鎖”列出的操作)需要資源的排他DDL鎖,阻止其他的可能修改和引用同一個模式對象的DDL操作的破壞性干擾。例如,在使用ALTER TABLE操作來爲表增加一行時,不能使用DROP TABLE操作來刪除表,反過來也是一樣。

在請求一個排他DDL鎖時,如果另外一個操作已經持有了這個模式對象的DDL鎖,需要等待老的DDL鎖釋放才能獲得鎖。

DDL操作還在修改的模式對象上獲得DML鎖(數據鎖)。

共享DDL鎖

某些DDL操作需要請求一個資源的共享DDL鎖,阻止衝突DDL操作的破壞性干擾,但允許類似DDL操作的數據併發。例如,當CREATE PROCEDURE語句運行時,包含的事務獲得所有引用表的共享DDL鎖。其他事務可以併發的創建引用同樣表的過程,因而也在同樣的表上獲得併發的共享DDL鎖,但是沒有事務可以獲得任何引用表的排他DDL鎖。所以,持有共享DDL鎖的事務確保引用的模式對象的定義在事務執行期間不會改變。

一個共享DDL鎖可以由包含下面的語句的DDL語句在模式對象上獲得:

AUDIT, NOAUDIT, COMMENT, CREATE [OR REPLACE] VIEW/ PROCEDURE/PACKAGE/PACKAGE BODY/FUNCTION/ TRIGGER, CREATE SYNONYM, 和CREATE TABLE (不包括CLUSTER參數)。

可中斷解析鎖

共享池中的SQL語句或PL/SQL程序單位持有每個引用模式對象的解析鎖。獲得一個引用對象的解析鎖,所以如果這個對象被修改或者刪除,相關的共享內存區域就無效了。解析鎖不禁止任何DDL操作,可以被任何衝突的DDL操作中斷,所以叫可中斷解析鎖。

解析鎖在SQL語句解析執行期間獲得,只要共享池中這個語句的共享內存區域存在就一直持有。

DDL鎖的生存週期

一個聚簇上的DDL操作在其中的聚簇和所有的表和實體化視圖上獲得排他DDL鎖。聚簇中的表或實體化視圖的DDL操作在聚簇上獲得共享鎖,在表或實體化視圖上獲得共享或排他DDL鎖。聚簇上的DDL鎖阻止其他操作在第一個操作執行時刪除聚簇。

閂和內部鎖

閂和內部鎖保護了內部的數據庫和內存結構。對用戶來說都是不可訪問的,因爲用戶不需要控制它們的存在和生存週期。下面解釋一下企業管理器的LOCKS和LATCHES監視器。

閂是簡單、低級別的串行性機制,用來保護系統全局區(SGA)中的共享數據結構。例如,閂保護了當前訪問數據庫的用戶列表和保護描述高速緩存中的塊的數據結構。服務器或後臺進程在處理和查看這些結構之一時,只需要獲得閂很短的時間。閂的實現是依賴操作系統的,特別是一個進程是否會等待閂和會等待閂多長時間。

內部鎖

內部鎖是比閂高級別的、更復雜的機制,服務於多個不同的目的。

字典緩存鎖

這些鎖是字典緩存的條目在它被修改或者使用時持有時間很短的一種鎖。它們確保語句解析時不會看到不一致的對象定義。

字典鎖可以是共享或排他的。共享鎖在解析完成時釋放,排他鎖在DDL操作結束時被釋放。

文件和日誌管理鎖

這些鎖用來保護不同的文件。例如,一個鎖保護控制文件,所以只有一個時間點只能有一個進程修改它。另一個鎖調節重做日誌文件的使用和歸檔。數據文件加鎖來確保多個實例以一個共享模式掛接數據庫,還是一個實例以排他模式掛接數據庫。因爲日誌和文件鎖顯示文件的狀態,這些鎖通常會被持有很長時間。

表空間和回滾段鎖

這些鎖保護表空間和回滾段。例如,多個訪問數據庫的實例必須對於一個表空間在線還是離線達成一致。回滾段加鎖所以只有一個實例可以寫入回滾段。

顯式(手動)數據鎖

Oracle通常自動執行鎖來確保數據併發、數據完整性和語句級別讀一致性。但是,你可以覆蓋Oracle的默認鎖機制。覆蓋默認鎖機制在下列情況下比較有用:

u 應用程序需要事務級別讀一致性或者重複讀。換句話說,它們中的查詢需要在事務存續期間必須產生一致性數據,不反映其他事務的改變。你可以通過覆蓋默認的鎖,或者使用顯式鎖、只讀事務、串行性事務來獲得事務級別讀一致性。

u 應用程序需要一個事務擁有一個資源的排他鎖,所以事務不需要等待其他事務的完成。

Oracle自動鎖可以在事務級別或者會話級別覆蓋。

在事務級別,包含下列SQL語句的事務覆蓋了Oracle默認鎖:

u SET TRANSACTION ISOLATION LEVEL語句

u LOCK TABLE語句(鎖定表或者使用視圖時的基表)

u SELECT ... FOR UPDATE語句

事務提交或者回滾之後釋放這些語句獲得的鎖。

在會話級別,會話可以使用ALTER SESSION語句來設置需要的事務隔離級別。

注意:如果在任何級別上覆蓋了Oracle默認鎖,數據庫管理員或者應用開發人員應該確保覆蓋鎖的過程正確操作。鎖的過程必須滿足下列準則:確保數據完整性、接受數據併發性、不存在死鎖或者有但可以適當的處理。

Oracle鎖管理服務

通過Oracle鎖管理服務,應用開發人員可以在PL/SQL塊中包含下列語句:

u 請求一個特定類型的鎖

u 給另一個過程的鎖一個可辨識的唯一名字,可以在同一個實例或者另一個實例

u 修改鎖類型

u 釋放鎖

因爲一個保留的用戶鎖和一個Oracle鎖相同,它也有所有的Oracle鎖功能,包括死鎖檢測。用戶鎖和Oracle鎖從不衝突,因爲它們的前綴爲UL。

Oracle鎖管理服務通過DBMS_LOCK包中的過程使用。

Oracle閃回查詢概述

Oracle閃回查詢允許你顯示和修改歷史數據。你可以在數據庫中使用特定的掛鐘時間或者用戶指定的系統修改號(SCN)來執行查詢。

閃回查詢使用Oracle的多版本度讀一致性來根據需要應用undo來恢復數據。Oracle數據庫10g自動調整一個叫撤銷持續週期的參數。撤銷持續週期指定了舊undo信息(提交事務的undo信息)在覆蓋之前必須保留的時間。數據庫收集使用統計,基於這些統計信息和undo表空間大小來調整撤銷持續週期。

使用閃回查詢可以查詢數據庫中早上、昨天或者上週存在的數據。這個操作的速度僅僅依賴於查詢的數據數量和數據需要回退的修改次數。

你可以查詢一個給定行或事務的歷史。使用保存在數據庫中的undo數據,你可以顯示一行的所有版本和返回這一行以前的版本。閃回查詢歷史讓你可以在事務級別檢查數據庫的修改。

你可以審計表的行和獲得修改行的事務信息以及行修改時間。通過事務ID,你可以通過LogMiner進行事務挖掘來獲得完整的事務信息。

你可以設置你想顯示的日期和時間,那麼在那個時間,任何你運行的SQL查詢在數據上的操作都存在。如果你是個認證用戶,那麼你可以修復錯誤,在不需要管理員介入的情況下回退到要恢復的數據。

通過SQL語句AS OF,你可以在查詢中爲每個表選擇不同的快照。將表和快照關聯就是表修飾。如果不使用快照來修改表,就會使用默認的快照。所有沒有指定快照的表獲得的都是相同的默認快照。

例如,假定你想寫一個查詢來查找過去一個小時創建的新用戶帳號。你可以在使用不同的AS OF子句修飾同一個表的兩個實例上實施操作。

DML和DDL操作可以使用表修飾來在子查詢中選擇快照。例如INSERT TABLE AS SELECT和CREATE TABLE AS SELECT的查詢可以在子查詢中使用表修飾來修復表中誤刪除的行。表修改可以是任何表達式:綁定變量、常量、字符串、日期操作等等。你可以打開一個遊標,並動態綁定一個快照值(時間戳或SCN)來修飾表。

閃回查詢的優勢

下面列舉了使用閃回查詢的優勢:

u 應用透明

打包程序,比如報表生成工具只需要查詢,可以使用登陸觸發器在閃回查詢模式運行。應用程序可以透明運行而不需要修改編碼。應用程序需要滿足的約束是確保有效,因爲截止閃回查詢時間只有一個一致性數據庫版本。

u 應用程序性能

如果應用程序需要恢復動作,它可以通過保存的SCN和閃回到這些SCN就可以了。這比保存數據集然後恢復他們要容易的多和快的多,前者在應用程序要需要回到指定的版本才需要。使用閃回查詢,不需要耗費指定版本導致的日誌記錄成本。

u 在線操作

閃回查詢是一個在線操作。閃回查詢的引用的對象可以被其他會話併發的DML和查詢。這些操作的速度不受影響。而且,不同的會話可以在同一個對象上併發的閃回到不同的閃回時間或SCN。閃回查詢的速度依賴於需要應用的undo量,這個和查詢要回退的時間成正比。

u 容易管理

相關用戶使用閃回查詢不需要額外的管理,除了適當的持續週期、擁有足夠的權限等等之外,不需要額外的權限,因爲過去的版本按照需要自動組織。

注意:

u 閃回查詢不撤銷任何操作。它只是一個查詢機制。在一些環境中,你可以從閃回查詢獲得輸出,自己執行撤銷。

u 閃回查詢並不告訴你改變了什麼。LogMiner做這個事情。

u 閃回查詢不撤銷修改,在你知道行需要回退的具體時間時效率很高。你可以使用它來將這個表回退到一個時間,但是如果表比較大,這是非常昂貴的,因爲它包含一個全表拷貝。

u 閃回查詢不支持DDL操作:修改行、刪除或截斷表。

u LogMiner對於獲得修改歷史非常優秀,但是它給你的是基於操作的(插入、更新、刪除),而不是基於一行的前後映像。這對於某些應用來說處理起來非常困難。

閃回查詢的默寫應用

這部分列出了使用閃回查詢的一些方式:

u 自我修復

你可以偶然刪除了一些重要的行,想恢復被刪除行。你可以回退到刪除的時間,來查看丟失的數據,然後將刪除的行插入當前表中。

u 電子郵件或語音郵件應用程序

你可能已經刪除了過去的郵件。使用閃回查詢,你可以回退到以前的時間來恢復刪除的郵件,將刪除的信息重新插入到當前郵箱

u 帳號餘額

你可以在截止一個月的特定日期顯示帳戶餘額。

u 打包應用程序

打包應用程序(比如報表生成工具)可以不需要修改任何應用程序邏輯就可以使用閃回查詢。應用程序期望的所有約束都滿足,因爲用戶截止給定時間或SCN可以看到數據庫的一致性版本。

另外,閃回查詢可以在審計信息檢查後用來查看數據的前映像。在DSS環境中,它可以從OLTP系統中截止一個一致的時間點抽取數據。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章