国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

當多個用戶訪問同一數據庫時會發生的現象

2024-07-21 02:43:23
字體:
來源:轉載
供稿:網友
使用單用戶數據庫時,每個事務都是順序執行的,而不必應付與其它事務的沖突。但是,在多用戶數據庫環境下,多個事務可以同步執行,并且每個事務都有可能與其它正在運行的事務發生沖突。在多用戶環境下,如果不將事務彼此隔離開來,就會發生四種現象:

丟失更新:

這種事件發生在兩個事務讀取和嘗試更新同一數據時,其中一個更新會丟失。例如:事務 1 和事務 2 讀取同一行數據,并都根據所讀取的數據計算出該行的新值。如果事務 1 用其新值更新該行以后,事務 2 又更新了同一行,則事務 1 所執行的更新操作就丟失了。由于設計的方法,DB2 通用數據庫不允許發生此類現象。

臟讀:

當事務讀取尚未提交的數據時,就會發生這種事件。例如:事務 1 更改了一行數據,而事務 2 在事務 1 提交更改之前讀取了已更改的行。如果事務 1 回滾該更改,則事務 2 就會讀取被認為是不曾存在的數據。

不可重復的讀:

當一個事務兩次讀取同一行數據,但每次獲得不同的數據值時,就會發生這種事件。例如:事務 1 讀取了一行數據,而事務 2 在更改或刪除該行后提交了更改。當事務 1 嘗試再次讀取該行時,它會檢索到不同的數據值(如果該行已經被更新的話),或發現該行不復存在了(如果該行被刪除的話)。

幻像:

當最初沒有看到某個與搜索條件匹配的數據行,而在稍后的讀操作中又看到該行時,就會發生這種事件。例如:事務 1 讀取滿足某個搜索條件的一組數據行,而事務 2 插入了與事務 1 搜索條件匹配的新行。如果事務 1 再次執行產生原先行集的查詢,則會檢索到不同的行集。

維護數據庫一致性和數據完整性,但又允許多個應用程序同時訪問同一數據,這樣的特性稱為并發性。DB2 通用數據庫嘗試用來強制執行并發性的方法之一是通過使用隔離級別,它決定在第一個事務訪問數據時,如何對其它事務鎖定或隔離該事務所使用的數據。DB2 通用數據庫使用下列隔離級別來強制執行并發性:

可重復的讀(Repeatable Read)

讀穩定性(Read Stability)

游標穩定性(Cursor Stability)

未提交的讀(Uncommitted Read)

我們將在接下來依次討論每種級別。

“可重復的讀”隔離級別

當使用可重復的讀隔離級別時,在單個事務執行期間鎖定該事務引用的所有行。使用這種隔離級別時,同一事務多次發出的同一個 SELECT 語句將始終產生同一結果;丟失更新、臟讀、不可重復的讀、幻像都不會發生。

使用可重復的讀隔離級別的事務可以多次檢索同一行集,并可以對它們執行任意次操作,直到由提交或回滾操作終止事務;不允許其它事務執行插入、更新或刪除操作,因為這些操作會在隔離事務存在期間影響正在被使用的行集。為了確保在“可重復的讀”隔離級別下運行的事務所訪問的數據不會受其它事務的負面影響,所以鎖定了該隔離事務所引用的每個行 — 而不是僅鎖定被實際檢索和/或修改的那些行。因此,如果一個事務掃描了 1000 行但只檢索 10 行,則所掃描的 1000 行(而不僅是被檢索的 10 行)都會被鎖定。

那么在現實環境中這個隔離級別是如何工作的呢?假定您擁有一家大型旅館,并有一個網站,該網站按“先到先服務”的原則接受客戶的房間預訂。如果您的旅館預訂應用程序是在“可重復的讀”隔離級別下運行的,當客戶檢索某個日期段內的所有可用房間列表時,您將無法更改那些房間在指定日期范圍內的費用,而其他客戶也將無法進行或取消將會更改該列表的預訂,直到生成該列表的事務終止為止。(對于第一個客戶的查詢所指定范圍之外的任何房間,您都可以更改房價,其他客戶也都可以進行或取消房間預訂。)

“讀穩定性”隔離級別

當使用讀穩定性隔離級別時,在單個事務執行期間,會鎖定該事務所檢索的所有行。當使用這種隔離級別時,直到隔離事務終止之前,其它事務不能更改隔離事務讀取的所有行。此外,其它事務對其它行所作的更改,在提交之前對于運行在“讀穩定性”隔離級別下的事務而言是不可見的。因此,當使用“讀穩定性”隔離級別時,在同一事務中多次發出 SELECT 語句可能會產生不同的結果。丟失更新、臟讀和不可重復的讀都不會發生;但是,有可能出現幻像。

使用“可重復的讀”隔離級別時,隔離事務引用的每一行都被鎖定;但是,在“讀穩定性”隔離級別下,只鎖定隔離事務實際檢索和/或修改的行。因此,如果一個事務掃描了 1000 行但只檢索 10 行,則只有被檢索到的 10 行(而不是所掃描的 1000 行)被鎖定。

那么,這種隔離級別會如何改變旅館預訂應用程序的工作方式呢?現在,當一個客戶檢索某個日期段內的所有可用房間列表時,您可以更改旅館中任何房間的房價,而其他客戶也可以取消在第一個客戶的查詢所指定的日期段內所保留房間的預訂。因此,如果在終止提交查詢的事務之前再次生成列表,則產生的新列表中有可能包含新的房價或第一次產生列表時不可用的房間。

“游標穩定性”隔離級別

當使用游標穩定性隔離級別時,只要隔離事務所用的游標定位在某一行上,就會鎖定該游標所引用的這一行。所獲取的鎖一直有效,直到游標重定位(通常通過調用 FETCH 語句)或隔離事務終止為止。因此,當使用這種隔離級別時,在同一事務中多次發出 SELECT 語句可能會產生不同的結果。丟失更新和臟讀不會發生;但有可能出現不可重復的讀和幻像。

當使用“游標穩定性”隔離級別的事務通過可更新游標從表中檢索行時,在游標定位在該行上時,其它事務不能更新或刪除該行。但是,如果被鎖定的行本身不是用索引訪問的,那么其它事務可以將新的行添加到表,并對位于被鎖定行前后的行進行更新和/或刪除操作。此外,如果隔離事務修改了它檢索到的任何行,那么在隔離事務終止之前,即使在游標不再位于這個被修改的行,其它事務不能更新或刪除該行。

 

其它事務在其它行上進行的更改,在提交之前對于使用“游標穩定性”隔離級別的事務是不可見的。缺省情況下,大多數事務都使用“游標穩定性”隔離級別。

這種隔離級別對旅館預訂應用程序有什么影響呢?現在,當一個客戶檢索某個日期段內的所有可用房間列表,然后查看關于所產生的列表上每個房間的信息時(每次查看一個房間),您可以更改旅館中任何房間的房價,而其他客戶可以對任何日期段的任何房間進行或取消預訂;唯一的例外是第一個客戶當前正在查看的房間。當第一個客戶查看列表中另一個房間的信息時,對于這個新房間也是一樣;您現在可以更改第一個客戶剛才查看的房間的房價,其他客戶也可以預訂該房間,但不能對第一個客戶當前正在查看的房間進行這些操作。

“未提交的讀”隔離級別

在使用未提交的讀隔離級別的情況中,當單個事務檢索行時,僅當另一個事務試圖刪除或更改被檢索的行所在的表時,才會在單個事務期間鎖定這些行。因為在使用這種隔離級別時,行通常保持未鎖定狀態,所以丟失更新、臟讀、不可重復的讀和幻像都可能會發生。

在大多數情況下,其它事務對行所作的更改,在提交或回滾之前對于使用“未提交的讀”隔離級別的事務是可見的。但是,此類事務不能看見或訪問其它事務所創建的表、視圖或索引,直到那些事務被提交為止。類似地,如果其它事務刪除了現有的表、視圖或索引,使用“未提交的讀”隔離級別的事務僅當進行刪除操作的事務終止時才能了解這一情況。這種行為有一個例外:當運行在“未提交的讀”隔離級別下的事務使用可更新游標時,該事務的行為和在“游標穩定性”隔離級別下運行一樣,并應用“游標穩定性”隔離級別的約束。

“未提交的讀”隔離級別通常用于那些訪問只讀表的事務和/或某些執行 SELECT 語句的事務,這些語句對其它事務的未提交數據沒有負面效果。

那么這種隔離級別對旅館預訂應用程序有什么影響呢?現在,當一個客戶檢索某個日期段內的所有可用房間列表時,您可以更改旅館中任何房間的房價,而其它客戶也可以對任何日期段內的任何房間進行或取消預訂。此外,如果其它客戶取消了預訂,即使他們還沒有終止其事務并將那些取消提交到數據庫,所生成的列表就可以包含這些取消預訂的房間了。

指定隔離級別

盡管隔離級別是控制如何為事務鎖定資源的,但實際上是在應用程序級別指定它們的。對于嵌入式 SQL 應用程序,是在預編譯時或將應用程序綁定到數據庫時指定要使用的隔離級別。在大多數情況下,應用程序的隔離級別是用受支持的編譯語言(如 C 或 C++)編寫的,通過 PRECOMPILE PROGRAM 和 BIND 命令/API 的 ISOLATION 選項來設置隔離級別。對于調用級接口(CLI)應用程序,所用的隔離級別是在應用程序運行時通過調用指定了 SQL_ATTR_TXN_ISOLATION 連接屬性的 SQLSetConnectAttr() 函數進行設置的。也可以通過指定TXNISOLATION 關鍵字的值來設置 CLI 應用程序的隔離級別,該關鍵字位于 db2cli.ini 配置文件中。對于 JDBC 和 SQLJ 應用程序,隔離級別是在應用程序運行時通過調用駐留在 java.sql 連接接口中的 setTransactionIsolation() 方法設置的。

當沒有指定隔離級別時,則缺省地使用“游標穩定性”隔離級別。對于從命令行處理器(CLP)執行的命令和腳本以及嵌入式 SQL、CLI、JDBC 和 SQLJ 應用程序都是如此。因此,也可以指定從 CLP 運行的命令和腳本所用的隔離級別;在這種情況下,所用的隔離級別是通過在建立與數據庫的連接之前在 CLP 中執行 CHANGE ISOLATION 命令設置的。

選擇適當的隔離級別

選擇用于事務的適當隔離級別是非常重要的。隔離級別不僅影響數據庫如何很好地支持并發性;而且影響包含該事務的應用程序的整體性能。這是因為獲取和釋放鎖所需的資源因隔離級別而異。

通常,使用的隔離級別越嚴格,對并發性提供的支持就越少,而整體性能可能會越低,因為要獲取并占有更多的資源。但是,當您確定將要使用的最佳隔離級別時,應該通過確定哪些現象可接受而哪些現象不可接受來進行決策。下列推斷可以用來幫助您確定在特定環境中使用哪種隔離級別:

如果您正在只讀數據庫上執行查詢,或者正在執行查詢而不考慮是否有未提交的數據值返回,則使用“未提交的讀”隔離級別。(需要是只讀事務 — 不需要較高的數據穩定性。)

如果您希望在不看見未提交數據值的情況下獲得最大的并發性,則使用“游標穩定性”隔離級別。(需要是讀/寫事務 — 不需要較高的數據穩定性。)

如果您希望獲得并發性,并希望限定的行在單個事務執行期間保持穩定,則使用“讀穩定性”隔離級別。(需要是只讀或讀/寫事務 — 需要較高的數據穩定性。)

如果您正在執行查詢,并且不希望看到對產生的結果數據集進行更改,則使用“可重復的讀”隔離級別。(需要是只讀事務 — 需要極高的數據穩定性。)


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 丹东市| 潢川县| 广水市| 大丰市| 博兴县| 丹寨县| 泾川县| 万载县| 中卫市| 高淳县| 上蔡县| 乌拉特后旗| 德清县| 河池市| 池州市| 商水县| 武平县| 长垣县| 荔浦县| 江阴市| 同江市| 洛浦县| 汽车| 温宿县| 巴塘县| 阜新市| 惠来县| 甘肃省| 海城市| 屯昌县| 镇巴县| 安平县| 桦南县| 怀安县| 通化市| 玛曲县| 尚义县| 绥滨县| 仁布县| 天镇县| 吉林省|