陳秋月,張劍妹
(長治學院 計算機系,山西 長治 046011)
隨著企業信息化建設的不斷深入,關系數據庫管理系統(RDBMS)目前成為諸多公司和大型企業的核心IT系統。數據庫是一個允許多個用戶共享的數據資源,但當多個用戶同時并發操作同一組數據時,就會損害數據庫的完整性和數據一致性。因此采用適當的方法對于協調多個事務并發操作,保證數據庫的完整性、正確性和一致性具有重要意義。
所謂事務是指用戶定義的一個數據庫操作序列,正確執行的事務應符合“ACID準則”,即原子性、持續性、一致性和隔離性。
(1)原子性(Atomicity):事務中包括的諸多操作要么全部執行,要么全部不執行。
(2)持續性(Consistency):一個事務一旦提交,它對數據庫中數據的改變是永久性的。
(3)一致性(Isolation):任何數據庫事務執行的結果必須是使數據庫從一個一致的狀態轉變到另一個一致的狀態。
(4)隔離性(Durability):一個事務的執行不能被其他事務所干擾。
多個事務如不加控制地并發執行,則會產生數據的不一致,這些數據不一致主要包括丟失修改、不可重復度和讀“臟”數據等,如圖1所示。

圖1 三種數據不一致性
(1)丟失修改(Lost Update):兩個事務對同一數據并發地寫入,其執行結果與串行地執行兩個事務的結果不一致。
(2)不可重復讀(Unrepeatable Read):因讀 -寫沖突引起,結果可能導致第二次讀的值與前次讀的值不同。
(3)讀“臟”數據(Dirty Read):因一事務讀另一事務尚未提交的數據引起,有可能讀到要回退的數據。
產生上述三類數據不一致性的原因是并發操作破壞了事務的隔離性。因此,事務并發執行時,通常采用封鎖技術來避免多用戶操作時數據的不一致。
所謂封鎖就是一個事務可以向系統申請對某數據對象加鎖,這樣事務就對該數據對象有了一定的控制權。
2.3.1 封鎖的粒度
封鎖粒度與系統的并發度和開銷密切相關。封鎖的粒度越大,并發度越低,系統開銷就越小;反之,封鎖的粒度越小,并發度就越高,但系統開銷也就越大。系統通常提供不同的封鎖粒度。鎖的粒度可以分為行、頁、鍵、盤區、表和數據庫。
2.3.2 封鎖的類型
常用的的封鎖類型有排它鎖(X鎖)和共享鎖(S鎖)。
(1)排它鎖:若事務T對數據A加上X鎖,則事務T可以讀取和修改A,其他事務不能再對A加任何類型的鎖,直到T釋放A上的X鎖。

圖2 使用封鎖機制解決三種數據不一致問題
(2)共享鎖:若事務T對數據對象A加上S鎖,則事務T可以讀A但不能修改A,其他事務只能再對A加S鎖,而不能加X鎖,直到T釋放A上的S鎖。
圖2給出了使用封鎖機制來解決圖1中的數據不一致性問題。
關系數據庫并發控制的實現途徑有很多種,其中最常用的有以下幾種:調整用戶工作模式,修改應用程序,避免不必要的并發;設置隔離級別,盡量讓一個事務工作專一;調整應用程序;利用開發工具的支持;借助于DBMS的功能。
這種方法適用于規模小、獨立性高、業務流程規范明確的系統。比如在圖書銷售系統中,只有銷售人員、庫管部門和銷售部門可以修改圖書數量。所以,在設計數據庫表時只需要在庫表中增加一個用戶列,在用戶操作時,把用戶列作為一個過濾條件,對應用程序的SQL語句做相應的調整。但是這種方法有其局限性,在分布式數據庫中,往往共享數據庫操作的客戶端比較多,這種情況下并發控制仍然是不可避免的。
隔離級別是事務準備接受不一致數據的級別,是事務與其他事務進行隔離的程度。當多個事務同時進行時,可以通過設置隔離級別來處理丟失修改、臟讀、不可重復讀。根據應用程序的業務邏輯采用不同的隔離級別是很重要的,降低隔離級別可以增加事務的并發度,但是會影響數據的一致性;反之可以保證數據的一致性,但可能造成事務阻塞等,對并發產生負面影響。所以,在并發事務執行過程中應設置恰當的隔離級別,盡量讓事務工作更專一。
有的關系數據庫系統并沒有提供并發控制的功能,例如Foxpro。在這種情況下要實現并發控制,通常需要在相應的數據庫表中增加一個時間戳字段。當用戶瀏覽記錄時先將時間戳值記到old_record(用戶的自定義變量)中,再將old_record中的內容記錄到新記錄new_record中,當用戶編輯new_record并提交時,比較old_record和原先的記錄中的時間戳,如果一樣,則表明沒有用戶修改原先的記錄,用new_record中的內容替換時間戳中的內容。反之則放棄修改。
目前,許多關系數據庫開發工具都具有一些方便的選項或部件來支持并發控制,如:Delphi和Powerbuilder。PowerBuilder中的并發控制技術主要通過設置Data Window的更新屬性來實現。其相關參數 Key Columns、Key and Updateable Columns、Key and Modified Columns為關系數據庫的并發操作提供了很好的支持。通過Data Window,開發人員無需編寫復雜的SQL語句,就可以實現對數據庫的讀寫操作,這為數據庫系統開發節約了大量時間成本。
上面討論的幾種方法都能夠較好的提高RDBMS的并發性能,但操作對象都不是由RDBMS自己來提供支持的。一般大型RDBMS都提供了比較好的并發控制功能,其通常采用自定義事務隔離級別、顯式加鎖等方式。

充分利用RDBMS自身所支持的并發控制功能無疑是實現并發控制的最好途徑之一,而典型的關系數據庫系統Sybase SQL Server就提供了這方面的支持。
例如一網上圖書銷售系統,同一時刻甲、乙兩地均有一客戶查詢到某圖書有剩余,并欲購買,此時如果該圖書只剩余了一本,那么問題就會產生:若甲客戶先買入圖書,則該圖書庫存就為零了,而乙客戶并不知道甲客戶已經購買,繼續購買該圖書,結果將會導致“無書仍售”現象。
SQL Server支持的鎖類型包括:共享鎖、排它鎖、更新鎖、架構鎖、意向鎖等。SQL Server會自動應用正確的鎖類型保證多用戶環境下數據的一致性。對于“無書仍售”問題,我們可以在執行銷售圖書后,在對圖書數目更新之前利用排它鎖查詢一下books表中現存的圖書數目。

SQL Server提供了4種隔離級別,用戶可以通過set transaction isolation level命令手工設置事務處理隔離層的鎖狀態。
(1)未提交讀(read uncommitted):當設置該選項時,可以讀取到已由其他事務修改但還未提交的數據。
(2)提交讀(read committed):該選項是 SQL Server的默認值。當設置該選項時,只能讀取其他事務提交的數據。
(3)可重復讀(repeatable read):當同一事物需要多次讀取同一數據,且必須保證每次讀取的數據相同時使用,以防止其他用戶更新數據。
(4)可串行讀(serializable):是四個隔離級別中限制最大的級別,事物之間完全隔離。
實現關系數據庫并發控制的途徑很多,但無論什么方法依據的基本原則都是:確保數據庫數據的一致性和正確性,并在此基礎上盡量提高事務的并發度。
[1]王珊,薩師煊.數據庫系統概論(第四版)[M].北京:高等教育出版社,2006.
[2]胡百靜,姚巧玫.SQL Server 2005數據庫開發詳解[M].北京:電子工業出版社,2006.
[3]張劍妹.數據庫的并發控制[J].晉東南師專學報,1999,(3):50-52.
[4]錢學忠,黃向前.基于SQL Server的實用并發控制技術[J].江南大學學報,2003,(3):240-244.