db2隔离级别锁并行性.docx
- 文档编号:11087077
- 上传时间:2023-05-29
- 格式:DOCX
- 页数:15
- 大小:53.26KB
db2隔离级别锁并行性.docx
《db2隔离级别锁并行性.docx》由会员分享,可在线阅读,更多相关《db2隔离级别锁并行性.docx(15页珍藏版)》请在冰点文库上搜索。
db2隔离级别锁并行性
並行性和隔離級別
在多個用戶處理資料庫時會發生的現象
在單用戶資料庫中,每個事務都按照順序執行,不會與其他事務發生衝突。
然而在多用戶資料庫環境中,多個事務可以同時執行,所以每個事務都有可能與其他正在運行的事務發生衝突。
當多用戶環境中的事務之間沒有互相隔離時,可能會出現四種類型的事件(或現象):
∙更新遺失:
當兩個事務讀取相同資料並試圖更新該資料時就會出現這種事件,結果其中一個事務作出的更新就會丟失。
舉例來說:
Transaction1和Transaction2讀取同一行資料,然後它們都根據所讀取的資料計算該行的新值。
如果Transaction1用它計算出的新值更新該行,而Transaction2隨後也更新了該行,那麼由Transaction1所執行的更新操作就會丟失。
∙錯誤讀取:
當事務讀取還未被發送的資料時,就會發生這種事件。
舉例來說:
Transaction1修改了一行資料,然後Transaction2在Transaction1還未發送修改操作之前讀取了被修改的行。
如果Transaction1回復了修改操作,那麼Transaction2讀取的資料就可以看作是從未存在過的。
∙不可重複的讀:
當事務兩次讀取同一行資料,但每次得到的資料都不一樣時,就會發生這種事件。
舉例來說:
Transaction1讀取一行資料,然後Transaction2修改或刪除該行並發送修改操作。
當Transaction1試圖重新讀取該行時,它就會得到不同的資料值(如果該行被更新)或發現該行不再存在(如果該行被刪除)。
∙虛讀:
如果符合搜索條件的一行資料在後面的讀取操作中出現,但該行資料卻不屬於最初的資料,就會發生這種事件。
舉例來說:
Transaction1讀取滿足某種搜索條件的一些行,然後Transaction2插入了符合Transaction1的搜索條件的一個新行。
如果Transaction1重新執行產生原來那些行的查詢,就會得到不同的行。
維護資料庫一致性和資料完整性,同時允許多個應用程式同時處理相同資料,這就叫作並行性。
DB2通用資料庫試圖實現並行性的方法之一就是使用隔離級別,這種方法將決定如何在處理事務中使用的資料時鎖定該資料或將其與其他事務隔離。
DB2通用資料庫使用下面的隔離級別來實現並行性:
∙可重複的讀(RepeatableRead)
∙讀穩定性(ReadStability)
∙游標穩定性(CursorStability)
∙未發送的讀(UncommittedRead)
"可重複的讀"隔離級別
當使用"可重複的讀"隔離級別時,單個事務引用的所有行在該事務執行期間都被鎖定。
使用這種隔離級別,同一事務中多次發出任何SELECT語句總會得到相同結果;更新遺失、錯誤讀取、不可重複的讀和虛讀都不會出現。
使用"可重複的讀"隔離級別的事務可以多次索引到相同的行的集合,並在這些行上執行任意多個操作(通過發送或回滾操作),直到事務終止;只要隔離事務存在,其他事務就不能執行會影響被使用行的集合的插入、更新或刪除操作。
為了保證運行在"可重複的讀"隔離級別之下的事務所處理的資料不會被其他事務錯誤地影響,隔離事務所引用的每一行都會被鎖定-而不僅僅是實際被索引或修改的那些行。
因此,如果事務掃描了1000行但只索引到10行,那麼掃描的這1000行全都會獲得並持有鎖-而不僅僅是被索引到的那10行。
"讀穩定性"隔離級別
當使用"讀穩定性"隔離級別時,單個事務索引到的所有行在該事務執行期間都將被鎖定。
當使用這種隔離級別時,隔離事務讀取的每一行在隔離事務終止前都不能被其他事務修改。
另外,運行在"讀穩定性"隔離級別下的事務將看不到其他事務對其他行作出的修改,直到這些修改被發送為止。
因此,當使用"讀穩定性"隔離級別時,在同一事務中多次發出的SELECT語句可能並不總會得出相同結果。
(更新遺失、錯誤讀取和不可重複的讀不會出現;而虛讀則可能會出現。
)
與"可重複的讀"隔離級別(隔離事務所引用的每一行都會被鎖定)不同,當使用"讀穩定性"隔離級別時,只有實際由隔離事務索引和(或)修改的那些行才會被鎖定。
因此,如果事務掃描了1000行但只索引到10行,那麼只有被索引到的那10行才會獲得並產生鎖定-而不是被掃描的1000行。
"游標穩定性"隔離級別
當使用"游標穩定性"隔離級別時,隔離事務使用的游標所引用的每一行在游標停留在該行期間都會被鎖定。
獲得的鎖定一直保持有效,直到游標被重新定位(通常是通過調用FETCH語句)或隔離事務終止。
因此,當使用這種隔離級別時,同一事務中多次發出的SELECT語句可能不會總產生相同結果。
(更新遺失和錯誤讀取都不會產生;然而不可重複的讀和虛讀可能會出現。
)
當使用"游標穩定性"隔離級別的事務通過可更新游標從表索引到一行時,在游標停留在該行時,其他事務都不能更新或刪除該行。
然而,如果被鎖定的行本身沒有使用索引來處理,那麼其他事務就可以向表添加新行,並在被鎖定行兩邊的行上執行更新和(或)刪除操作。
此外,如果隔離事務修改了它索引到的任意一行,在隔離事務終止之前其他事務都不能更新或刪除該行,甚至在游標不再停留在修改過的行上之後也不能。
使用"游標穩定性"隔離級別的事務看不到其他事務對其他行作出的修改,直到這些修改被發送為止。
預設情況下,"游標穩定性"隔離級別是大部分事務所使用的隔離級別。
"未發送的讀"隔離級別
當使用"未發送的讀"隔離級別時,如果另一個事務試圖撤銷或修改索引的行所在的表,那麼單個事務索引到的行只在該事務執行期間被鎖定。
因為使用這種隔離級別時一般不會鎖定行,所以更新遺失、錯誤讀取、不可重複的讀和虛讀都可能出現。
多數情況下,使用"未發送的讀"隔離級別的事務在其他事務對行作出的修改被發送或回滾之前都可以看到這些修改。
然而,這樣的事務不能看到、也不能處理由其他事務創建的表、事務或索引,直到這些事務被發送為止。
同樣,使用"未發送的讀"隔離級別的事務在事務終止時只能看到另一個事務刪除已有的表、視圖或索引。
這種行為有一個例外情況:
當運行在"未發送的讀"隔離級別之下的事務使用可更新的游標時,該事務就好像運行在"游標穩定性"隔離級別下,而且"游標穩定性"隔離級別的約束因素也會被應用。
"未發送的讀"隔離級別通常用於處理唯讀表的事務和(或)執行對其他事務的未發送資料沒有負面效果的SELECT語句的事務。
指定隔離級別
儘管隔離級別將控制事務鎖定資源的方式,它們實際上是在應用程式層指定的。
對於嵌入式SQL應用程式來說,要使用的隔離級別是在預編譯或應用程式綁定到資料庫時指定的。
多數情況下,用所支援的編譯語言(如C和C++)編寫的應用程式隔離級別是通過PRECOMPILEPROGRAM的ISOLATION選項和BIND命令/API來設置的。
對於調用層介面(CLI)應用程式來說,要使用的隔離級別是通過使用指定的SQL_ATTR_TXN_ISOLATION連接屬性調用SQLSetConnectAttr()函數而在應用程式運行時設置的。
CLI應用程式的隔離級別還可以通過向TXNISOLATION關鍵字(它可以在db2cli.ini配置檔中找到)分配一個值來設置。
在JDBC和SQLJ應用程式中,隔離級別是在應用程式運行時通過調用駐留在java.sq連接介面中的setTransactionIsolation方法設置的。
當沒有指定隔離級別時,"游標穩定性"隔離級別是預設情況下使用的。
對於從命令行處理器執行的命令和腳本以及內嵌式SQL、CLI、JDBC和SQLJ應用程式來說,都是這樣的。
因此,從命令行處理器運行的命令和腳本使用的隔離級別也可以被指定;在這種情況下,要使用的隔離級別是通過執行CHANGEISOLATION命令設置的。
選擇正確的隔離級別
為事務選擇合適的隔離級別來使用是很重要的。
隔離級別不僅影響到資料庫支援並行性的優良程度,它還會影響包含事務的應用程式的整體性能。
這是因為獲取和釋放鎖所需的資源隨著每種隔離級別而不同。
通常,使用越嚴格的隔離級別,就會得到越少的並行性支援,而且整體性能可能會降低,因為要獲得更多的資源。
然而,在決定要使用的最佳隔離級別時,什麼現象可以接受以及什麼現象不能接受應該是決定因素。
您可以使用下面的啟示來幫助自己決定在特定情況下使用哪種隔離級別:
∙如果您要執行唯讀資料庫上的查詢,或者您要執行某種查詢而不需要考慮是否返回未發送資料,請使用"未發送的讀"隔離級別。
(需要唯讀事務-不需要很高的資料穩定性。
)
∙如果您需要最高的並行性,而不願看到未發送資料值,那麼請使用"游標穩定性"隔離級別。
(需要讀/寫事務-不需要很高的資料穩定性。
)
∙如果您需要並行性,並希望符合條件的行在單個事務執行期間保持穩定,那麼請使用"讀穩定性"隔離級別。
(需要唯讀或讀/寫事務-需要很高的資料穩定性。
)
∙如果您要執行某種查詢,而且不希望看到對產生的結果資料集作出修改,請使用"可重複的讀"隔離級別。
(需要唯讀事務-需要極高的資料穩定性。
)
鎖
鎖定如何工作
在並行性和隔離級別這一章中,我們看到DB2通用資料庫通過使用鎖來隔離不同的事務。
鎖是用於將資料資源與單個事務進行關聯的一種機制,目的在於控制資源在和擁有它的事務關聯期間其他事務與該資源交互的方式。
(與被鎖定的資源關聯的事務被稱為"持有"或"擁有"該鎖。
)DB2資料庫管理器(DB2DatabaseManager)使用鎖來防止事務處理其他事務寫入的未發送資料(除非使用了"未發送的讀"隔離級別),並防止其他事務在擁有鎖的事務使用嚴格的隔離級別時對行進行更新。
一旦事務獲取了鎖,鎖在擁有它的事務終止前一直保持有效-在事務終止時,鎖被釋放,其他事務就可以使用被鎖定的資料資源了。
如果一個事務試圖用與另一個事務持有的鎖不相容的方式處理資料資源(我們將簡單地討論一下鎖相容性),該事務必須等到擁有鎖的事務結束才能進行處理。
這被稱為鎖等待。
當發生鎖等待事件時,試圖處理資料資源的事務只是停止執行,直到擁有鎖的事務終止而不相容的鎖被釋放為止。
鎖屬性
所有的鎖都有下面的基本屬性:
∙Object:
object屬性標識被鎖定的資料資源。
DB2資料庫管理器每當需要時獲取資料資源上的鎖,比如表空間、表和行。
∙Size:
size屬性指定被鎖定的資料資源部分的物理大小。
鎖並不需要一直控制整個資料資源。
舉例來說,DB2資料庫管理器可以賦予應用程式對表中特定一行獨佔的控制,而不是賦予應用程式對整個表的獨佔控制。
∙Duration:
duration屬性指定鎖持續的時間長度。
事務的隔離級別通常控制鎖的持續時間。
∙Mode:
mode屬性指定鎖的擁有者被允許的處理類型以及被鎖定資料資源的並行用戶被允許的處理類型。
該屬性通常被稱為鎖狀態。
鎖狀態-鎖類型
鎖的狀態決定鎖的擁有者被允許的處理類型以及鎖定資料資源的並行用戶被允許的處理類型。
下面的列表指出了可用的鎖狀態,順序是增加控制的順序:
鎖狀態(模式):
IntentNone(IN)
可用對象:
表空間和表
描述:
鎖的擁有者可以讀取鎖定的表中的資料,包括未發送的資料,但不能修改該資料。
在這種模式中,鎖的擁有者不獲取行級鎖;因此,其他並行應用程式能夠讀取和修改表中的資料。
鎖狀態(模式):
IntentShare(IS)
可用對象:
表空間和表
描述:
鎖的擁有者可以讀取鎖定的表中的資料,但不能修改該資料。
還是因為鎖的擁有者不獲取行級鎖,所以其他併發應用程式可以讀取和修改表中的資料。
(當事務在表上擁有IntentShare鎖時,它在讀取的每一行上獲取Share鎖。
)當事務不傳達更新表中行的意圖時,將獲得這種鎖。
鎖狀態(模式):
NextKeyShare(NS)
可用對象:
行
描述:
鎖的擁有者和所有並行事務都能讀取,但不能修改鎖定行中的資料。
獲得這種鎖可以代替使用"讀穩定性"或"游標穩定性"事務隔離級別讀取的資料上的Share鎖。
鎖狀態(模式):
Share(S)
可用對象:
表和行
描述:
鎖的擁有者和任何其他併發事務都可以讀取,但不能修改鎖定的表或行中的資料。
只要表不是被Share鎖鎖定的,表中的單個行還是能夠被Share鎖鎖定。
然而,如果表被Share鎖鎖定了,鎖的擁有者就不能獲取該表中的行級Share鎖了。
如果表或行被Share鎖鎖定,其他並行事務都可以讀取資料,但不能修改資料。
鎖狀態(模式):
IntentExclusive(IX)
可用對象:
表空間和表
描述:
鎖的擁有者和其他並行應用程式都可以讀取和修改鎖定的表中的資料。
當鎖的擁有者從表讀取資料時,它在讀到的每一行上都獲取一個Share鎖,並在其更新的每一行上獲取Update鎖和Exclusive鎖。
其他並行應用程式都可以讀取和更新被鎖定的表。
當事務傳達更新表中行的意圖時,就會獲得這種鎖。
(SELECTFORUPDATE、UPDATE...WHERE和INSERT語句傳達更新的意圖。
)
鎖狀態(模式):
ShareWithIntentExclusive(SIX)
可用對象:
表
描述:
鎖的擁有者可以讀取和閱讀被鎖定的表中的資料。
鎖的擁有者在它更新的行上獲取Exclusive鎖,但並不在它讀取的行上獲得鎖;因此,其他併發應用程式能夠讀取但不能更新被鎖定的表中的資料。
鎖狀態(模式):
Update(U)
可用對象:
表和行
描述:
鎖的擁有者可以更新被鎖定的表中的資料,而且鎖的擁有者在它更新的行上自動獲取Exclusive鎖。
其他並行應用程式可以讀取但不能更新被鎖定表中的資料。
鎖狀態(模式):
NextKeyExclusive(NX)
可用對象:
行
描述:
鎖的用戶可以讀取但不能修改被鎖定行的資料。
當從表的索引中刪除行或向索引插入行時,表中的下一行上將獲得這種鎖。
鎖狀態(模式):
NextKeyWeakExclusive(NW)
可用對象:
行
描述:
鎖的擁有者可以讀取但不能修改被鎖定行。
當向非目錄表的索引插入行時,表中的下一行上將獲得這種鎖。
鎖狀態(模式):
Exclusive(X)
可用對象:
表和行
描述:
鎖的擁有者可以讀取和修改被鎖定表或行中的clusive(WE)
可用對象:
行
描述:
鎖的擁有者可以讀取和修改被鎖定的行。
當向非目錄表中插入一行時,該行上將獲得這種鎖。
鎖狀態(模式):
SuperExclusive(Z)
可用對象:
表空間和表
描述:
鎖的擁有者可以修改表、刪除表、創建索引或刪除索引。
每當事務試圖執行其中任一種操作時,表上就會自動獲得這種鎖。
其他的並行事務在該鎖被刪除前都不被允許讀取或更新該表。
鎖相容性
如果資料資源上的一個鎖的狀態使另一個鎖可以放在相同資源上,就可以說這兩個鎖(或狀態)是相容的。
每當事務在一個資料資源上擁有鎖,而第二個事務對同一資源請求相同的鎖時,DB2資料庫管理器就檢查兩個鎖的狀態,決定它們是否相容。
如果兩個鎖互相相容,鎖就被賦予給第二個事務(條件是沒有其他的事務在等待該資料資源)。
然而,如果鎖不相容,那麼第二個事務必須等到第一個事務釋放它的鎖(實際上第二個事務必須等到全部已有的不相容鎖被釋放),才能夠獲得對資源的處理權並繼續處理。
請參閱IBMDB2UniversalDatabaseAdministrationGuide:
Performance文檔以瞭解哪些鎖相容及哪些鎖不相容的特定資訊。
鎖轉換
當事務試圖處理它已經持有鎖的資料資源,而且所需的處理模式需要比已有鎖更嚴格的鎖時,持有的鎖的狀態就會被改變為更嚴格的狀態。
將已經持有的鎖的狀態改變為更嚴格的狀態,這樣的操作被稱為鎖轉換。
鎖轉換的發生是因為事務在資料資源上一次只能持有一個鎖。
多數情況下,鎖轉換是為行級鎖執行的,而轉換過程非常簡單。
舉例來說,如果已經持有一個Share(S)或一個Update(U)行級鎖,並需要一個Exclusive(X)鎖,持有的鎖就會被轉換為Exclusive(X)鎖。
然而,IntentExclusive(IX)鎖和Share(S)鎖是特殊的情況,因為它們都不會被認為比另一種更嚴格。
所以,如果持有這裏的其中一個行級鎖而請求另一種的話,持有的鎖就會被轉換為SharewithIntentExclusive(SIX)鎖。
如果請求的鎖狀態更嚴格,那麼類似的轉換就會導致請求鎖的狀態變為持有鎖的新的鎖狀態。
(鎖轉換只在持有鎖增加嚴格性的情況下出現。
)一旦鎖狀態被轉換,鎖會一直保持所獲取的最高的狀態,直到持有鎖的事務終止。
鎖定升級
所有的鎖都需要存儲空間,而且因為可用的空間不是無限的,DB2資料庫管理器必須限制可以用於鎖定的空間(這是通過資料庫配置參數maxlocks實現的)。
為了避免特定資料庫代理超過已建立的鎖空間限制,每當獲得過多(任意類型的)鎖時,將自動執行一個名為鎖定升級的進程。
鎖定升級就是將同一個表中幾個單獨的行級鎖轉換為一個單獨的表級鎖。
因為鎖定升級是內部處理的,所以在外部可以看到的結果可能只是一個或多個表上並行處理的減少。
下面我將介紹鎖定升級如何工作:
當事務請求一個鎖,而鎖存儲空間已滿時,與事務關聯的一個表將被選擇,事務獲得一個表級鎖,所有該表的行級鎖都被釋放(從而在鎖列表資料結構中創建空間),然後表級鎖被添加到鎖列表。
如果這個過程還沒有釋放出足夠的空間,另一個表就會被選擇,然後一直重複該過程,直到有足夠可用空間為止。
這時,事務獲得了所需的鎖並繼續執行。
然而,如果在事務所有的行級鎖都被升級後還沒有得到所需的鎖空間,事務就會被請求發送或回滾自初始化後所作的所有修改(也就是產生一個SQL錯誤代碼),然後事務被終止。
鎖死
兩個或更多事務間的鎖爭用有時候會導致被稱為鎖死的情況。
說明鎖死如何發生的最好方法就是舉例說明:
假定Transaction1在TableA上獲得Exclusive(X),Transaction2在TableB上獲得Exclusive(X)鎖。
然後,假定Transaction1試圖在TableB上獲得Exclusive(X)鎖,而Transaction2試圖在TableA上獲得Exclusive(X)鎖。
兩個事務的執行過程都將被掛起,直到它們的第二個鎖請求被通過。
然而,因為在其中一個事務釋放它當前持有的鎖之前(通過執行發送或回滾操作),兩個事務的鎖請求都不能被通過,而且兩個事務都不能釋放它當前持有的鎖(因為兩個事務都被掛起並等待鎖請求的通過),所以就會出現鎖死情況。
當出現鎖死情況時,除非某個外部代理程式採取行動,否則所有相關的事務都會無限期地等待鎖被釋放。
DB2通用資料庫中處理鎖死的方法是一個名為鎖死檢測器的非同步系統後臺進程。
鎖死檢測器的唯一職責就是定位和解決在鎖定的子系統中發現的任何鎖死。
鎖死檢測器大部分時間內都處於"休眠"狀態,不過會在預先設置的時間間隔被"喚醒"以決定是否存在鎖死情況。
如果鎖死檢測器在鎖定的子系統中發現了鎖死,它就會選擇、終止並回滾相關的一個事務。
(被終止和回滾的那個事務將收到SQL錯誤代碼,它獲得的所有鎖都會被釋放。
)通常,剩餘的事務(多個事務)就可以繼續執行了。
鎖超時
只要事務在特定資料資源上(例如表或行)持有鎖,其他事務就可能被拒絕處理該資料資源,直到擁有鎖的事務終止並釋放它獲得的所有鎖為止。
如果預先沒有某種鎖超時檢測機制,事務就可能無限期地等待鎖被釋放。
舉例來說,當事務在等待另一個用戶的應用程式持有的鎖被釋放,而該用戶離開了他的工作站,卻沒有執行某種交互好讓其他應用程式可以終止擁有鎖的事務,就會出現這種情況。
顯然,這些類型的情況能夠導致極差的應用程式性能。
為了避免在這些類型的情況出現時阻礙其他應用程式的執行,我們可以在資料庫配置檔中指定一個鎖超時值(通過資料庫配置參數locktimeout實現)。
在使用這個參數時,它會控制任何事務等待獲取請求的鎖的時間量。
如果在指定的時間間隔過去之後還沒有獲得需要的鎖,等待的應用程式就會收到錯誤資訊,然後請求鎖的事務就被回滾。
通過使用鎖超時可以避免全局鎖死的情況,特別是在分散式事務應用程式環境中。
如何獲取鎖
多數情況下,DB2資料庫管理器在需要鎖時會隱式地獲取鎖,而這些鎖在DB2資料庫管理器的控制下。
例外情況是,如果使用"未發送的讀"隔離級別,事務就不必顯式地請求鎖。
實際上,事務能夠顯式地鎖定的資料庫物件只有表物件。
下面的說明展示了用於決定為引用的物件應該獲取何種類型的鎖的邏輯:
DB2資料庫管理器總試圖獲取行級鎖。
然而,這種行為可以通過執行特殊類型的ALTERTABLE語句進行修改。
這種形式的ALTERTABLE語句的句法是:
ALTERTABLE[TableName]LOCKSIZETABLE
在這裏:
TableName:
標識已有表的名稱,在處理這種表時,所有事務都要獲取它的表級鎖。
對於特定的事務,我們還可以通過執行LOCKTABLE語句強迫DB2資料庫管理器在表上獲取表級鎖。
該語句的句法是:
LOCKTABLE[TableName]IN[SHARE|EXCLUSIVE]MODE
在這裏:
TableName:
標識已有表的名稱,對於這種表應該獲取表級鎖(前提是其他事務在該表上沒有不相容的鎖)。
如果該語句執行時指定了SHARE模式,就會獲得一個允許其他事務讀取但不能修改存儲在其中的資料的表級鎖;如果執行時指定了EXCLUSIVE模式,那麼就會獲得一個不允許其他事務讀取或修改存儲在表中資料的表級鎖。
並行性和粒度
前面提到過,只要事務在特定資料資源上持有鎖,其他事務就無法獲取對該資料資源的處理權,直到擁有鎖的事務終止。
因此,如果要為了得到最大並行性而進行優化,行級鎖通常比表級鎖更好,因為它們將處理權限制在較小的資源上。
然而,因為獲得的每個鎖都需要一定的存儲空間和處理時間才能夠管理,所以單個表級鎖比幾個不同的行級鎖需要的成本更少。
除非另行指定,預設情況下將獲得行級鎖。
鎖的粒度(即獲得行級鎖還是表級鎖)可以通過使用ALTERTABLE...LOCKSIZETABLE、ALTERTABLE...LOCKSIZEROW和LOCKTABLE語句進行控制。
ALTERTABLE...LOCKSIZETABLE語句為實現粒度提供了一種全局方法,它的結果是處理特定表中行的所有事務都獲得表級鎖。
而LOCKTABLE語句則允許在單一事務級別獲取表級鎖。
執行這兩種語句之後,事務在需要鎖時都會獲得單個的Share(S)或Exclusive(X)表級鎖。
結果,因為只有一個表級鎖必須獲得並釋放,而不是幾個不同的行級鎖,所以整體性能通常會提高。
影響
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- db2 隔离 级别 并行