摘要:由于故障如果造成一些不可分割的操作中斷,就會(huì)使數(shù)據(jù)處于一種不一致的錯(cuò)誤狀態(tài)。本文通過實(shí)例來討論了如何利用事務(wù)的ACID特性使功能上不允許中斷的操作遇到故障后仍然保持其操作的不間斷性,從而保證了數(shù)據(jù)庫(kù)的一致性。
關(guān)鍵詞:事務(wù);一致性;數(shù)據(jù)庫(kù)
中圖分類號(hào):TP311文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):1009-3044(2008)28-0035-02
The Use of Thansaction in Maintaining Database's Consistency
GUO Xiao-yan1, ZHANG Ming2
(1. Electronand Information Technology Institute of Lanzhou Jiaotong University, Lanzhou 730070, China; 2. Computer Department of Lanzhou City University, Lanzhou 730070, China)
Abstract: Some inalienable operation interrupt because of the database trouble, will cause the data to be at a inconsistent error status. In this article we use the example to discuss that some operations that can not be interrupt will maintain their operation's continuity with thansction's ACID characteristic.
Key words: Thansaction; Consistency; database
1 引言
事務(wù)是一個(gè)操作序列,這些操作要么執(zhí)行,要么不執(zhí)行,它是一個(gè)不可分割的工作單位。事務(wù)是并發(fā)控制和數(shù)據(jù)庫(kù)恢復(fù)的基本單位,它具有原子性、一致性、隔離性、持久性四大特點(diǎn)(ACID),這對(duì)維護(hù)數(shù)據(jù)庫(kù)的一致性非常重要。如在銀行轉(zhuǎn)帳過程中,從一個(gè)帳號(hào)中提款和將這筆款存入另一個(gè)帳號(hào)是不可分割的兩個(gè)操作,但是如果提款成功了,但于某種原因?qū)⑦@筆錢存入另一帳號(hào)時(shí)發(fā)生錯(cuò)誤,那么提款的操作也要被撤消,否則數(shù)據(jù)庫(kù)就會(huì)出現(xiàn)不一致性錯(cuò)誤。為解決以下問題,就可以將不可分割的操作定義在事務(wù)中,以保證其原子性。
2 事務(wù)故障
在理想情況情況下,提交給數(shù)據(jù)庫(kù)管理系統(tǒng)的操作都可正常執(zhí)行,但這些操作在實(shí)際執(zhí)行過程中,經(jīng)常會(huì)由于如網(wǎng)絡(luò)中斷、掉電等原因而出錯(cuò),如果將這些操作定義在事務(wù)中,可解決以上問題。但在事務(wù)執(zhí)行的過程中,運(yùn)算溢出,并發(fā)事務(wù)發(fā)生死鎖,違反某些完整性限制等,也會(huì)引起事務(wù)中操作的中斷,從而引起事務(wù)故障。事務(wù)的故障是事務(wù)沒有達(dá)到預(yù)期的終點(diǎn),因此數(shù)據(jù)庫(kù)可能處于不一致的狀態(tài)。如果發(fā)生事務(wù)故障,通常采用事務(wù)的回滾(rollback)來撤銷該事務(wù)中已執(zhí)行的操作,使該事務(wù)好象根本沒有啟動(dòng)一樣,從而保證相關(guān)操作的不間斷性。
3 利用事務(wù)保持?jǐn)?shù)據(jù)庫(kù)一致性示例
3.1 由于故障產(chǎn)生數(shù)據(jù)庫(kù)不一致性問題
示例:將001帳號(hào)中減去10000元給002帳號(hào)
對(duì)于銀行轉(zhuǎn)帳過程而言,假定用戶信息存在use_table關(guān)系中(附各帳號(hào)初值),如表1所示。
use_id:用戶帳號(hào)
use_number:某帳號(hào)下的金額
對(duì)于以上關(guān)系,在SQL SERVER中可以實(shí)現(xiàn)如下:
create table use_table
(
use_id int,-- 定義use_id字段
use_number int check(use_number<70000)/*定義use_number字段,并為該字段加入約束,其值不能超過70000*/
)
如果不利用事務(wù),可將轉(zhuǎn)帳過程程序模擬如下:
update use_table --從001帳號(hào)中減去10000元
set use_number=use_number-10000
where use_id='001'
update use_table--在002帳號(hào)中加上10000元
setuse_number=use_number+10000
where use_id='002'
如執(zhí)行一次以上轉(zhuǎn)帳程序,表1中的數(shù)據(jù)如圖1所示,圖1中的數(shù)據(jù)為期望結(jié)果:
■
圖1 執(zhí)行轉(zhuǎn)帳程序一次后的結(jié)果
但如果執(zhí)行第二次轉(zhuǎn)帳程序,在SQL SERVET的查詢分析器中會(huì)有圖2錯(cuò)誤產(chǎn)生,同時(shí)表中的數(shù)據(jù)如圖3所示:
■
圖2 執(zhí)行第二次轉(zhuǎn)帳程序后的報(bào)錯(cuò)
■
圖3 執(zhí)行第二次轉(zhuǎn)帳程序后數(shù)據(jù)庫(kù)中的數(shù)據(jù)
分析以上錯(cuò)誤產(chǎn)生的原因?yàn)槌绦蛟趫?zhí)行的過程中違反了數(shù)據(jù)庫(kù)的完整性約束,從而出現(xiàn)了故障。在第二次執(zhí)行轉(zhuǎn)帳程序時(shí),給001帳號(hào)減去10000元后,剩余的金額為20000元,期望給002帳號(hào)增加10000元,使其金額為70000元,但是違反了use_mumber字段不能超過70000的約束,因此出現(xiàn)了給001帳號(hào)減去金額成功,而給002號(hào)帳戶加入金額失敗的情況,使數(shù)據(jù)庫(kù)出現(xiàn)了不一致的錯(cuò)誤,如圖3所示,這種情況是實(shí)際情況中完全需要避免的。
3.2 解決辦法
如果利用事務(wù),使轉(zhuǎn)帳的兩個(gè)過程成為一個(gè)整體,則可避免以上錯(cuò)誤,為此可將轉(zhuǎn)帳程序改造如下:
declare @x int
set @x=0
begin transaction m
update m3
set number=number-4000
where useid='001'
set @x=@x+@@rowcount --如果以上更新執(zhí)行成功,則@x的值會(huì)增1
update m3
set number=number+4000
where useid='002'
set @x=@x+@@rowcount --如果以上更新執(zhí)行成功,則@x的值再會(huì)增1
if @x=2--如果兩個(gè)過程都成功完成,則提交事務(wù)
begin
commit transaction m
end
else/*如果只有一個(gè)完成,則回滾事務(wù),使數(shù)據(jù)庫(kù)回到該事務(wù)執(zhí)行之前的狀態(tài)*/
rollback transaction m
print @x
4 結(jié)束語(yǔ)
為了保證一些操作執(zhí)行的不間斷性,可以將這些操作定義在事務(wù)中,但在事務(wù)執(zhí)行的過程中,仍然有可能發(fā)生故障,只要在應(yīng)用程序中進(jìn)行判斷,如果事務(wù)中的所有操作都已執(zhí)行,則提交事務(wù)(commit),如果有些操作沒有執(zhí)行,則要回滾事務(wù)(rollback),使數(shù)據(jù)回到執(zhí)行此事務(wù)之前的一致狀態(tài)。本文中引用銀行轉(zhuǎn)帳的事例,在操作時(shí),只用到了一個(gè)關(guān)系,如果對(duì)于涉及多個(gè)關(guān)系的較為復(fù)雜的情況,只需根據(jù)情況修改應(yīng)程序既可。
參考文獻(xiàn):
[1] 李國(guó)彬,趙麗娟,沈淑清,等. SQL Server 2000應(yīng)用基礎(chǔ)與實(shí)訓(xùn)教程[M]. 西安:西安電子科技大學(xué)出版社,2006.
[2] 王珊,薩師煊. 數(shù)據(jù)庫(kù)系統(tǒng)概論[M]. 三版. 北京:高等教育出版社,2006.
[3] 關(guān)敬敏,沈立強(qiáng),李莉. SQL Server數(shù)據(jù)庫(kù)應(yīng)用教程[M]. 北京:清華大學(xué)出版社,2005.