《數(shù)據(jù)庫(kù)系統(tǒng)-基礎(chǔ)、設(shè)計(jì)及應(yīng)用》課件第7章_第1頁(yè)
《數(shù)據(jù)庫(kù)系統(tǒng)-基礎(chǔ)、設(shè)計(jì)及應(yīng)用》課件第7章_第2頁(yè)
《數(shù)據(jù)庫(kù)系統(tǒng)-基礎(chǔ)、設(shè)計(jì)及應(yīng)用》課件第7章_第3頁(yè)
《數(shù)據(jù)庫(kù)系統(tǒng)-基礎(chǔ)、設(shè)計(jì)及應(yīng)用》課件第7章_第4頁(yè)
《數(shù)據(jù)庫(kù)系統(tǒng)-基礎(chǔ)、設(shè)計(jì)及應(yīng)用》課件第7章_第5頁(yè)
已閱讀5頁(yè),還剩89頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

7.1事務(wù)的概念

7.2事務(wù)的基本操作

7.3封鎖機(jī)制

7.4封鎖的問(wèn)題及解決方法

7.5數(shù)據(jù)庫(kù)恢復(fù)技術(shù)

實(shí)驗(yàn)7事務(wù)管理與數(shù)據(jù)庫(kù)備份

第7章事務(wù)管理

7.1.1引入事務(wù)處理的必要性

實(shí)際數(shù)據(jù)庫(kù)操作中,一個(gè)操作常與其他操作具有某種程度的關(guān)聯(lián)。只有將這些互相關(guān)聯(lián)的操作作為一個(gè)整體來(lái)進(jìn)行,才能保證它們的正確性。例如,假定銀行要將“張京”賬戶上的9800元錢轉(zhuǎn)入“王瑩”賬戶,需要連續(xù)執(zhí)行兩步操作:

●從張京”賬戶上取出9800元;

●為“王瑩”賬戶存入9800元。7.1事?務(wù)?的?概?念

【例7-1】假定火車售票系統(tǒng)中有“售票”和“車次”兩個(gè)表,分別登記各代售點(diǎn)累計(jì)售出的車票數(shù)與全部車次的剩余票數(shù),其關(guān)系模式為

售票(代售點(diǎn)號(hào),車次,日期,售出票數(shù))

車次(車次,日期,剩余票數(shù))

現(xiàn)在A0110售票點(diǎn)打算代售3張K236車次2012年10月20日的車票,需要執(zhí)行以下操作:

S1N←查詢K236車次2012年10月20日的“剩余票數(shù)”;

S2如果N<2,則

拒絕操作并通知車票數(shù)不足;

否則{

更新A0110代售點(diǎn)的“售出票數(shù)”;

更新K236車次的“剩余票數(shù)”;

}步驟S1可由一個(gè)SELECT語(yǔ)句來(lái)完成:

SELECT剩余票數(shù)

FROM車次

WHERE車次='K236'AND日期='2012-10-20';

步驟S2按照S1操作的結(jié)果來(lái)決定能不能售票并對(duì)兩個(gè)表進(jìn)行更新操作,如果剩余票數(shù)多于請(qǐng)求票數(shù)(3張),則可用下面兩個(gè)語(yǔ)句更新“售票”表和“車次”表:/*更新A0110代售點(diǎn)K236車次2012年10月20日的“售出票數(shù)”*/

UPDATE售票

SET售出票數(shù)=售出票數(shù)+3

WHERE代售點(diǎn)號(hào)='A0110'AND車次='K236'AND日期='2012-10-20'

/*更新K236車次2012年10月20日的“剩余票數(shù)”*/

UPDATE車次

SET剩余票數(shù)=剩余票數(shù)-3

WHERE車次='K236'AND日期='2012-10-20';如果兩個(gè)UPDATE語(yǔ)句都能夠成功執(zhí)行,則將協(xié)同完成“A0110代售點(diǎn)售出3張K236車次2012年10月20日車票”這個(gè)任務(wù)。但是,如果第一個(gè)UPDATE語(yǔ)句執(zhí)行成功后,系統(tǒng)隨之發(fā)生故障,則有可能出現(xiàn)問(wèn)題:假定K236次火車共有1200張車票,2012年10月20日的車票已售出了1197張,其中A0110代售點(diǎn)售出了150張,剩余車票3張。在第1個(gè)UPDATE語(yǔ)句成功執(zhí)行后,A0110代售點(diǎn)的“售出票數(shù)”更新為153。當(dāng)排除了系統(tǒng)故障并重新提供服務(wù)時(shí),如果另一個(gè)代售點(diǎn)又請(qǐng)求代售3張K236車次2012年10月20日車票,則將因K236車次的“剩余票數(shù)”尚未更新而再次售出3張,結(jié)果多售出了3張車票。導(dǎo)致這種錯(cuò)誤的原因是系統(tǒng)重新提供服務(wù)時(shí),數(shù)據(jù)庫(kù)的當(dāng)前狀態(tài)與它所描述的客觀事物當(dāng)前的實(shí)際狀態(tài)是不一致的。為了解決這樣的問(wèn)題,DBMS引入了事務(wù)處理機(jī)制,允許用戶將一系列具有內(nèi)在聯(lián)系的操作定義為一個(gè)事務(wù),一個(gè)事務(wù)就是一個(gè)邏輯單元,可以采取相應(yīng)的策略來(lái)保證一個(gè)邏輯單元內(nèi)的操作要么全部執(zhí)行要么都不執(zhí)行。

在數(shù)據(jù)庫(kù)系統(tǒng)上執(zhí)行并發(fā)操作時(shí),事務(wù)是作為最小的控制單元來(lái)使用的。對(duì)于DBMS來(lái)說(shuō),一個(gè)事務(wù)就是一個(gè)不可分割的邏輯上的工作單元。如果一次只允許一個(gè)用戶使用,則該系統(tǒng)為單用戶系統(tǒng);如果允許多個(gè)用戶同時(shí)使用,則該系統(tǒng)為多用戶系統(tǒng)。在多用戶系統(tǒng)中,經(jīng)常會(huì)遇到多個(gè)用戶執(zhí)行并發(fā)操作的情況,可將事務(wù)作為執(zhí)行這種并發(fā)操作的最小控制單元。7.1.2事務(wù)的特點(diǎn)

1.事務(wù)結(jié)束語(yǔ)句

DBMS中的事務(wù)類似于操作系統(tǒng)中的進(jìn)程,進(jìn)程是操作系統(tǒng)中分配系統(tǒng)資源和進(jìn)行處理機(jī)調(diào)度的基本單元。而DBMS中的事務(wù)是資源競(jìng)爭(zhēng)、并發(fā)控制和恢復(fù)的基本單元。它是由數(shù)據(jù)庫(kù)操縱語(yǔ)言(如SQL)或者程序設(shè)計(jì)語(yǔ)言(如C、C++、Java)提供的事務(wù)開(kāi)始語(yǔ)句、事務(wù)結(jié)束語(yǔ)句定界的一系列數(shù)據(jù)庫(kù)操作語(yǔ)句構(gòu)成的。通常有兩種事務(wù)結(jié)束語(yǔ)句:

(1)事務(wù)提交:將成功完成的事務(wù)的執(zhí)行結(jié)果(即更新)永久化,并釋放事務(wù)占有的全部資源。

(2)事務(wù)回滾:中止當(dāng)前事務(wù),撤銷對(duì)數(shù)據(jù)庫(kù)所做的更新,并釋放事務(wù)占有的全部資源。

2.事務(wù)的類型

SQLServer數(shù)據(jù)庫(kù)提供了三種類型的事務(wù)模式:顯式事務(wù)、隱式事務(wù)和自定義事務(wù)。

(1)顯式事務(wù)是指顯式地定義其開(kāi)始和結(jié)束的事務(wù),又稱為用戶定義事務(wù)。當(dāng)使用BEGINTRAN和COMMIT語(yǔ)句時(shí)發(fā)生顯式事務(wù)。

(2)隱式事務(wù)是指在當(dāng)前事務(wù)提交或回滾后自動(dòng)開(kāi)始的事務(wù),需要用COMMIT語(yǔ)句和ROLLBACK語(yǔ)句回滾或結(jié)束事務(wù)。

(3)自動(dòng)提交事務(wù)是指能夠自動(dòng)執(zhí)行并自動(dòng)回滾的事務(wù),即當(dāng)一個(gè)語(yǔ)句成功執(zhí)行后,事務(wù)被自動(dòng)提交;當(dāng)執(zhí)行過(guò)程中產(chǎn)生錯(cuò)誤時(shí),將會(huì)執(zhí)行事務(wù)回滾的操作。

【例7-2】用SQLServer提供的顯式事務(wù)模式定義例7-1中的數(shù)據(jù)庫(kù)更新事務(wù)。

BEGINTRANSACTION

UPDATE售票

SET售出票數(shù)=售出票數(shù)+3

WHERE代售點(diǎn)號(hào)='A0110'AND車次='K236'AND日期='2012-10-20'

UPDATE車次

SET剩余票數(shù)=剩余票數(shù)-3

WHERE車次='K236'AND日期='2012-10-20'

COMMITTRANSACTION;

3.事務(wù)的特點(diǎn)

為了事務(wù)能夠并發(fā)執(zhí)行且當(dāng)發(fā)生故障時(shí)保證數(shù)據(jù)的完整性,事務(wù)應(yīng)該具備以下特性。

(1)原子性:事務(wù)是由不可分割的操作序列構(gòu)成的工作單元,由事務(wù)管理子系統(tǒng)完成。事務(wù)中的全部元素作為一個(gè)整體提交或回滾。如果一個(gè)事務(wù)執(zhí)行失敗,DBMS能夠保證已經(jīng)執(zhí)行了的那些操作不反映到數(shù)據(jù)庫(kù)中。例如,銀行轉(zhuǎn)賬時(shí)通過(guò)一個(gè)事務(wù)更新兩個(gè)賬戶的存款余額,如果該事務(wù)提交了,則這兩個(gè)賬戶都會(huì)更新;如果事務(wù)在執(zhí)行了第一個(gè)更新語(yǔ)句后因出現(xiàn)故障而不能執(zhí)行第二個(gè)更新語(yǔ)句,則在數(shù)據(jù)庫(kù)恢復(fù)時(shí)將會(huì)消除第一個(gè)更新語(yǔ)句對(duì)數(shù)據(jù)庫(kù)的影響。

(2)一致性:一個(gè)事務(wù)不能違背定義在數(shù)據(jù)庫(kù)中的任何完整性檢查。為了維護(hù)數(shù)據(jù)的一致性,所有的規(guī)則、約束、檢查都會(huì)被應(yīng)用到事務(wù)中。因?yàn)樗械臄?shù)據(jù)更改都是在事務(wù)執(zhí)行期間進(jìn)行的,因而這些數(shù)據(jù)在事務(wù)開(kāi)始和結(jié)束之前能夠確保一致。例如,在銀行系統(tǒng)中,事務(wù)開(kāi)始前,兩個(gè)賬戶余額的總額處于一致的狀態(tài),事務(wù)進(jìn)行過(guò)程中,一個(gè)賬戶余額改變,另一個(gè)賬戶余額未變,則這兩個(gè)賬戶余額的總額處于不一致?tīng)顟B(tài),事務(wù)完成后,賬戶余額的總額即恢復(fù)為一致的狀態(tài)。

(3)隔離性:由并發(fā)事務(wù)所做的修改必須與任何其他并發(fā)事務(wù)所做的修改隔離。在事務(wù)查看數(shù)據(jù)時(shí),數(shù)據(jù)所處的狀態(tài)要么是另一并發(fā)事務(wù)修改它之前的狀態(tài),要么是另一事務(wù)修改它之后的狀態(tài),事務(wù)不會(huì)查看中間狀態(tài)的數(shù)據(jù)。這稱為可串行性,因?yàn)樗軌蛑匦卵b載起始數(shù)據(jù),并且重播一系列事務(wù),以使數(shù)據(jù)結(jié)束時(shí)的狀態(tài)與原始事務(wù)執(zhí)行的狀態(tài)相同。

注:當(dāng)事務(wù)執(zhí)行修改數(shù)據(jù)操作時(shí),如果任何其他進(jìn)程正在同時(shí)使用相同的數(shù)據(jù),則直到該事務(wù)成功提交后,對(duì)數(shù)據(jù)的修改才能生效。

(4)永久性:事務(wù)在提交之后,所做的工作將會(huì)永久保存下來(lái),即使硬件和應(yīng)用程序發(fā)生錯(cuò)誤,也必須保證對(duì)數(shù)據(jù)所做的修改不受影響。7.2.1啟動(dòng)事務(wù)

事務(wù)啟動(dòng)標(biāo)記一個(gè)顯式本地事務(wù)的起點(diǎn)。事務(wù)一旦啟動(dòng),便會(huì)一直執(zhí)行下去,直到其中所有操作都準(zhǔn)確無(wú)誤地完成之后,使用COMMITTRANSACTION語(yǔ)句將該事務(wù)對(duì)數(shù)據(jù)庫(kù)中數(shù)據(jù)的操作結(jié)果永久地保存在數(shù)據(jù)庫(kù)中,如果在運(yùn)行事務(wù)的過(guò)程中遇到了錯(cuò)誤,則BEGINTRANSACTION命令之后的所有數(shù)據(jù)操作都將進(jìn)行回滾,將數(shù)據(jù)庫(kù)中數(shù)據(jù)恢復(fù)到該事務(wù)執(zhí)行之前的狀態(tài)。7.2事務(wù)的基本操作

SQLServer中,可以通過(guò)BEGINTRANSACTION命令啟動(dòng)事務(wù)。該命令的一般形式為

BEGIN

TRAN[SACTION]

[事務(wù)名|@事務(wù)名變量]

[WITH

MARK['字符串']]

其中,“事務(wù)名”即該事務(wù)的名稱;“@事務(wù)名變量”表示用變量來(lái)指定事務(wù)的名稱,并且變量只能聲明為char、nchar、varchar和nvarchar幾種數(shù)據(jù)類型;WITHMARK表示指定在日志中的標(biāo)記事務(wù);“字符串”表示描述被標(biāo)記的字符串。一個(gè)BEGINTRANSACTION語(yǔ)句與其后的一條COMMITTRANSACTION語(yǔ)句之間的所有事情作為單個(gè)事務(wù)。如果SQLServer遇到一條COMMINT

TRANSACTION語(yǔ)句,那么保存自最近一條BEGIN

TRANSACTION語(yǔ)句之后對(duì)數(shù)據(jù)庫(kù)所做的工作;如果SQLServer遇到一條ROLLBACK

TRANSACTION語(yǔ)句,則將拋棄所有這些工作。

事務(wù)是可以嵌套的,原則是必須先提交或回退內(nèi)層事務(wù),然后再提交或回退外層事務(wù),換句話說(shuō),一條COMMIT

TRANSACTION或ROLLBACK

TRANSACTION語(yǔ)句對(duì)應(yīng)最近的一條BEGIN

TRANSACTION語(yǔ)句。

注:也可使用STARTTRANSACTION命令實(shí)現(xiàn)開(kāi)始事務(wù),其用法和功能與BEGINTRANSACTION命令類似。

【例7-3】使用BEGINTRANSACTION命令啟動(dòng)事務(wù)myTrans。

USE

dbTest;

/*打開(kāi)數(shù)據(jù)庫(kù)dbTest*/

GO

DECLARE

@myTrans

varchar(20);

/*本行及下一行聲明了事務(wù)名稱*/

select

@myTrans='myTransName';

BEGIN

TRANSACTION

@myTrans;

/*啟動(dòng)事務(wù)*/

GO

SELECT

*

FROM

存貨/*本行及下一行設(shè)置執(zhí)行事務(wù)的內(nèi)容*/

ORDER

BY

貨號(hào)

GO

【例7-4】使用WITHMARK命令為事務(wù)logTrans建立一個(gè)標(biāo)記。

USE

dbTest;

GO

BEGIN

TRANSACTION

logTrans

WITH

MARK

'查詢存貨表中的存貨量數(shù)據(jù)'

GO

SELECT

*

FROM

存貨

ORDER

BY

貨號(hào)

GO

7.2.2提交事務(wù)

使用COMMITTRANSACTION命令來(lái)實(shí)現(xiàn)事務(wù)的提交操作。事務(wù)提交標(biāo)志著一個(gè)成功的從BEGINTRANSACTION開(kāi)始的事務(wù)(隱性事務(wù)或顯式事務(wù))的結(jié)束,使得自從事務(wù)開(kāi)始以來(lái)所執(zhí)行的所有數(shù)據(jù)修改的結(jié)果成為數(shù)據(jù)庫(kù)的永久部分,并釋放事務(wù)所占用的資源。

數(shù)據(jù)庫(kù)中為了保證數(shù)據(jù)的完整性和一致性,通常要在內(nèi)存中建立一個(gè)工作區(qū),用于完成對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作處理的各種事務(wù),這些處理結(jié)果在COMMIT命令執(zhí)行之前并未保存到數(shù)據(jù)庫(kù)中,只有在執(zhí)行COMMIT命令之后,內(nèi)存工作區(qū)的內(nèi)容才被寫(xiě)入數(shù)據(jù)庫(kù)。這樣可以確保數(shù)據(jù)庫(kù)中數(shù)據(jù)的完整性和一致性。COMMITTRANSACTION命令的一般形式為

COMMIT

{TRAN

|

TRANSACTION}[事務(wù)名

|

@事務(wù)名變量]

發(fā)布一條COMMIT

TRANSACTION語(yǔ)句時(shí),SQLServer將最近的一個(gè)已啟動(dòng)事務(wù)標(biāo)記為準(zhǔn)備提交。只有在提交一個(gè)嵌套事務(wù)系列中的最外層事務(wù)時(shí),SQLServer才將所有修改都寫(xiě)入到數(shù)據(jù)庫(kù)中。用戶的責(zé)任是保證在做完了所有預(yù)期的修改之后再發(fā)布COMMIT

TRANSACTION語(yǔ)句。一旦提交了一個(gè)事務(wù),就再也不能回退它了。

【例7-5】使用BEGINTRANSACTION命令啟動(dòng)事務(wù)myTrans,并使用COMMITTRANSACTION命令提交該事務(wù)。USE

dbTest;

GO

DECLARE

@myTrans

varchar(20);

select

@myTrans='myTransName';

BEGIN

TRANSACTION

@myTrans;

GO

SELECT

*

FROM

存貨

ORDER

BY

貨號(hào)

GO

COMMIT

TRANSACTION

GO

7.2.3回滾事務(wù)

用戶可以使用ROLLBACKTRANSACTION語(yǔ)句實(shí)現(xiàn)回滾事務(wù)的操作?;貪L事務(wù)是指取消自事務(wù)的起點(diǎn)或保存點(diǎn)到事務(wù)結(jié)束后的所有操作?;貪L后系統(tǒng)將釋放由事務(wù)控制的資源。ROLLBACKTRANSACTION語(yǔ)句的一般形式為

ROLLBACK

{TRAN

|

TRANSACTION}[

事務(wù)名

|

@事務(wù)名變量

|

保存點(diǎn)名]

其中,“事務(wù)名”表示回滾事務(wù)的名稱;“@事務(wù)名變量”表示用戶定義的包含有效事務(wù)名稱變量的名稱;“保存點(diǎn)名”是用戶在事務(wù)中設(shè)置的保存點(diǎn)的名稱,保存點(diǎn)可以定義在按條件取消某個(gè)事務(wù)的一部分后該事務(wù)可以返回的一個(gè)位置??梢酝ㄟ^(guò)回滾到起點(diǎn)而完全取消事務(wù),此時(shí),ROLLBACKTRANSACTION語(yǔ)句拋棄自最近一條BEGIN

TRANSACTION語(yǔ)句以后的所有操作結(jié)果;也可以將事務(wù)回滾到保存點(diǎn),再按需要完成剩余的SQL語(yǔ)句和COMMITTRANSACTION語(yǔ)句;ROLLBACKTRANSACTION語(yǔ)句無(wú)法回退嵌套事務(wù)系列中的單個(gè)事務(wù)。而總是回退到嵌套事務(wù)系列當(dāng)中的第一個(gè)事務(wù)(最外層事務(wù))。

如果需要取消整個(gè)事務(wù),使用“ROLLBACKTRANSACTION事務(wù)名”語(yǔ)句實(shí)現(xiàn)。

事務(wù)開(kāi)始后,事務(wù)處理期間使用的資源會(huì)一直保留,直到事務(wù)完成(即鎖定)。如果將事務(wù)的一部分回滾到保存點(diǎn),則將繼續(xù)保留資源直到事務(wù)完成或者回滾整個(gè)事務(wù)為止。

【例7-6】定義一個(gè)事務(wù),通過(guò)事務(wù)將“存貨”表中“貨名”為“應(yīng)急燈”的單價(jià)修改為91,然后再使用ROLLBACKTRANSACTION語(yǔ)句將該事務(wù)回滾。

BEGIN

TRANSACTION

UPDATE

存貨

SET

單價(jià)=91

WHERE

貨名='應(yīng)急燈'

ROLLBACK

TRANSACTION

SELECT

*

FROM

存貨

7.2.4設(shè)置事務(wù)保存點(diǎn)

使用事務(wù)時(shí),用戶可以在事務(wù)內(nèi)部設(shè)置事務(wù)保存點(diǎn),以備必要時(shí)回滾到這個(gè)保存點(diǎn)。在執(zhí)行事務(wù)的過(guò)程中,如果需要按條件回滾到預(yù)先設(shè)定的事務(wù)保存點(diǎn),則撤銷該保存點(diǎn)之后的操作即可。

如果遇到錯(cuò)誤的可能性較小而且預(yù)先檢查更新的有效性的代價(jià)較高,則使用保存點(diǎn)將會(huì)非常有效。例如,應(yīng)用程序在客戶訂單中插入一條訂貨記錄時(shí),需要查驗(yàn)本公司是否有訂單所需求的存貨,但查驗(yàn)可用存貨量的工作因需多方查詢而代價(jià)較大,考慮到該公司具備有效的供應(yīng)商和分購(gòu)點(diǎn),存貨不足的可能性很小,故可將應(yīng)用程序設(shè)計(jì)為不先驗(yàn)貨而直接更新訂單,只需在收到存貨不足的信息時(shí),回滾到這個(gè)更新操作之前即可。實(shí)現(xiàn)這個(gè)功能的方法是:在插入訂貨記錄的操作之前設(shè)置一個(gè)事務(wù)保存點(diǎn),以備存貨不足時(shí)撤銷插入操作。在事務(wù)內(nèi)部設(shè)置事務(wù)保存點(diǎn)使用SAVETRANSACTION語(yǔ)句來(lái)實(shí)現(xiàn),該語(yǔ)句的一般形式為

SAVE

{TRAN

|

TRANSACTION}[保存點(diǎn)名

|

@保存點(diǎn)名變量]

其中,“保存點(diǎn)名”表示設(shè)置事務(wù)保存點(diǎn)的名稱;“@保存點(diǎn)名變量”表示包含有效保存點(diǎn)名稱的用戶定義變量的名稱。

設(shè)置了事務(wù)保存點(diǎn)之后,便可執(zhí)行“ROLLBACKTRANSACTION保存點(diǎn)名”語(yǔ)句回滾到保存點(diǎn)(不回滾到事務(wù)的起點(diǎn))。

【例7-7】定義一個(gè)事務(wù),通過(guò)事務(wù)將“存貨”表中名稱為“應(yīng)急燈”的數(shù)據(jù)記錄刪除,并在事務(wù)中定義保存點(diǎn),保存點(diǎn)的名稱為markSave。

BEGIN

TRANSACTION

/*啟動(dòng)事務(wù)*/

DELETE

FROM

存貨

/*這兩行設(shè)置事務(wù)保存點(diǎn)之前執(zhí)行的操作*/

WHERE

貨名='應(yīng)急燈'

SAVE

TRANSACTION

markSave

/*設(shè)置事務(wù)保存點(diǎn)markSave*/

DELETE

FROM

存貨

/*這兩行設(shè)置事務(wù)保存點(diǎn)之后執(zhí)行的操作*/

WHERE

貨名='鉗子'

ROLLBACK

TRANSACTION

Save_Goods

/*回滾到事務(wù)保存點(diǎn)markSave*/

SELECT

*

FROM

存貨

封鎖機(jī)制是并發(fā)控制的主要手段,是多個(gè)用戶能夠同時(shí)操縱同一個(gè)數(shù)據(jù)庫(kù)中數(shù)據(jù)而不發(fā)生數(shù)據(jù)不一致現(xiàn)象的重要保障。

注:?jiǎn)蜟PU的計(jì)算機(jī)系統(tǒng)中,同一時(shí)間只能由一個(gè)事務(wù)占用CPU進(jìn)行處理。所謂的并發(fā)訪問(wèn)實(shí)質(zhì)上是多個(gè)事務(wù)交叉使用CPU。7.3封鎖機(jī)制7.3.1并發(fā)操作可能出現(xiàn)的問(wèn)題

如果多個(gè)涉及數(shù)據(jù)庫(kù)中數(shù)據(jù)更新的操作需要并發(fā)執(zhí)行,則應(yīng)該加以限制,否則可能會(huì)產(chǎn)生數(shù)據(jù)不一致問(wèn)題。

【例7-8】并發(fā)操作不加以限制時(shí)產(chǎn)生的數(shù)據(jù)不一致性問(wèn)題。

假設(shè),一個(gè)商店中涉及某種商品的兩宗業(yè)務(wù)如下:

進(jìn)貨:存貨100件,再購(gòu)進(jìn)200件。需要執(zhí)行進(jìn)貨事務(wù)來(lái)為存貨量加200,用T1表示。

銷售:售出80件,需要執(zhí)行銷售事務(wù)來(lái)將存貨量減80,用T2表示。

1)丟失更新結(jié)果

如果同時(shí)發(fā)生進(jìn)貨操作和銷售操作,則形成并發(fā)操作。在“進(jìn)貨”讀取存貨量之后,“銷售”也讀取了同一存貨量;“進(jìn)貨”修改存貨量而回寫(xiě)更新后的值;“銷售”修改存貨量也回寫(xiě)更新后的值。此時(shí)存貨量為“銷售”回寫(xiě)的值,“進(jìn)貨”對(duì)存貨量的更新丟失。例如,按圖7-1(a)所示的順序來(lái)執(zhí)行進(jìn)貨與銷售的并發(fā)操作時(shí),發(fā)生了“丟失更新”錯(cuò)誤。圖7-1進(jìn)貨和銷售操作并發(fā)執(zhí)行時(shí)產(chǎn)生的問(wèn)題

2)讀“臟數(shù)據(jù)”

在進(jìn)貨事務(wù)與銷售事務(wù)并發(fā)執(zhí)行時(shí),如果進(jìn)貨事務(wù)對(duì)數(shù)據(jù)庫(kù)更新的結(jié)果提交之前,銷售事務(wù)就使用了進(jìn)貨的結(jié)果,而在進(jìn)貨事務(wù)之后銷售操作又回滾,則會(huì)因銷售事務(wù)讀取了進(jìn)貨操作的“臟數(shù)據(jù)”而出錯(cuò)。例如,按圖7-1(b)所示的順序進(jìn)行并發(fā)操作時(shí),就產(chǎn)生了這種錯(cuò)誤。

3)不可重復(fù)讀

在進(jìn)貨事務(wù)讀取存貨量A之后,銷售事務(wù)執(zhí)行了對(duì)A的更新,當(dāng)進(jìn)貨事務(wù)再次讀取數(shù)據(jù)A(希望與第一次等值)時(shí),得到的數(shù)據(jù)與前一次不同,這時(shí)引起的錯(cuò)誤稱為“不可重復(fù)讀”。圖7-1(c)所示并發(fā)操作執(zhí)行過(guò)程中,發(fā)生了“不可重復(fù)讀”錯(cuò)誤。7.3.2鎖的概念

當(dāng)數(shù)據(jù)庫(kù)中多個(gè)事務(wù)并發(fā)執(zhí)行時(shí),事務(wù)的隔離性并不總能加以保證。DBMS需要采取一定的措施對(duì)并發(fā)執(zhí)行的事務(wù)之間的相互影響加以控制。這種并發(fā)控制機(jī)制大體上分為悲觀的和樂(lè)觀的兩種。

悲觀的并發(fā)控制方法基于數(shù)據(jù)庫(kù)的一致性經(jīng)常會(huì)被破壞的認(rèn)識(shí),在事務(wù)訪問(wèn)數(shù)據(jù)庫(kù)對(duì)象之前采取一定的措施加以控制,只有得到訪問(wèn)許可的事務(wù)才能訪問(wèn)指定的數(shù)據(jù)庫(kù)對(duì)象。為當(dāng)前事務(wù)所使用的數(shù)據(jù)庫(kù)對(duì)象加鎖就是悲觀的并發(fā)控制方法。樂(lè)觀的并發(fā)控制方法基于數(shù)據(jù)庫(kù)的一致性被破壞的可能性較小的認(rèn)識(shí),允許事務(wù)執(zhí)行時(shí)直接訪問(wèn)數(shù)據(jù)庫(kù)對(duì)象,只在事務(wù)結(jié)束時(shí)才驗(yàn)證數(shù)據(jù)庫(kù)的一致性是否遭到破壞。基于有效性驗(yàn)證的方法就是樂(lè)觀的并發(fā)控制方法。

加鎖是處理多用戶并發(fā)訪問(wèn)的重要方法。鎖是一個(gè)事務(wù)防止另一個(gè)事務(wù)訪問(wèn)自用資源,實(shí)現(xiàn)當(dāng)前事務(wù)與其他事務(wù)并發(fā)訪問(wèn)數(shù)據(jù)庫(kù)中數(shù)據(jù)的一種主要手段?;诩渔i的并發(fā)控制方法的基本思想是:當(dāng)事務(wù)T需要訪問(wèn)數(shù)據(jù)庫(kù)對(duì)象Q時(shí),先申請(qǐng)對(duì)Q的鎖。如果經(jīng)批準(zhǔn)得到了,則T繼續(xù)執(zhí)行,而且此后不允許其他事務(wù)修改Q,直到事務(wù)T釋放Q上的鎖為止。也就是說(shuō),當(dāng)一個(gè)用戶鎖住數(shù)據(jù)庫(kù)中某個(gè)對(duì)象時(shí),其他用戶就不能再訪問(wèn)它。封鎖具有如下三個(gè)環(huán)節(jié):

(1)申請(qǐng)加鎖,即事務(wù)在操作前對(duì)待用的數(shù)據(jù)提出加鎖請(qǐng)求;

(2)獲得鎖,即當(dāng)條件成熟時(shí),事務(wù)在系統(tǒng)允許時(shí)獲得數(shù)據(jù)的控制權(quán);

(3)釋放鎖,即事務(wù)在完成操作后放棄數(shù)據(jù)的控制權(quán)。

為了達(dá)到封鎖的目的,使用時(shí)事務(wù)應(yīng)選擇合適的鎖,并應(yīng)遵從一定的封鎖協(xié)議。

在DBMS中為數(shù)據(jù)庫(kù)對(duì)象加鎖時(shí),除了能夠?qū)Σ煌馁Y源加鎖之外,還可以使用不同程度的加鎖方式,如SQLServer中可以使用共享鎖、更新鎖、結(jié)構(gòu)鎖等。其中,基本鎖有兩種類型:排他鎖(ExclusiveLocks,簡(jiǎn)稱X鎖)和共享鎖(ShareLocks,簡(jiǎn)稱S鎖)。排他鎖又稱為獨(dú)占鎖或?qū)戞i。一旦事務(wù)對(duì)某個(gè)數(shù)據(jù)對(duì)象加上了排他鎖,則只允許該事務(wù)讀取和修改這個(gè)數(shù)據(jù)對(duì)象,其他任何事務(wù)既不能讀取和修改這個(gè)數(shù)據(jù)對(duì)象,也不能再對(duì)它加任何類型的鎖,直到該事務(wù)釋放這個(gè)對(duì)象上的鎖為止。

共享鎖又稱為讀鎖。如果一個(gè)事務(wù)對(duì)某個(gè)數(shù)據(jù)對(duì)象加上了共享鎖,則其他事務(wù)只能對(duì)這個(gè)數(shù)據(jù)對(duì)象再加共享鎖而不能加排他鎖,直到該事務(wù)釋放了這個(gè)數(shù)據(jù)對(duì)象上的共享鎖

為止。

封鎖方法要求每個(gè)事務(wù)都要根據(jù)自己對(duì)數(shù)據(jù)對(duì)象的操作類型(讀、寫(xiě)或讀寫(xiě))向事務(wù)管理器申請(qǐng)適當(dāng)?shù)逆i:讀操作申請(qǐng)S鎖,寫(xiě)操作或讀寫(xiě)操作申請(qǐng)X鎖。事務(wù)管理器收到封鎖請(qǐng)求后,按封鎖相容性原則判斷是否滿足該事務(wù)的加鎖請(qǐng)求。事務(wù)只有得到授予的鎖之后,才能繼續(xù)其操作,否則只能等待。

所謂“鎖相容”指的是:如果事務(wù)T1已持有數(shù)據(jù)對(duì)象Q的某種鎖,則當(dāng)T2申請(qǐng)對(duì)Q的鎖時(shí),批準(zhǔn)T2獲得即稱為T2的申請(qǐng)鎖類型與T1的持有鎖類型相容;否則稱為不相容。

基本鎖類型的相容性原則是:共享鎖與共享鎖相容;排他鎖與共享鎖以及排他鎖與排他鎖都是不相容的,如圖7-2所示。圖7-2封鎖相容性矩陣7.3.3封鎖協(xié)議

1.一級(jí)封鎖協(xié)議

一級(jí)封鎖協(xié)議是:一個(gè)事務(wù)在修改數(shù)據(jù)之前,必須先對(duì)其加上自己的X鎖,直到該事務(wù)結(jié)束才釋放它。事務(wù)結(jié)束包括正常結(jié)束(提交)和非正常結(jié)束(回滾)。根據(jù)協(xié)議的要求,將圖7-3中的任務(wù)T1和T2作為事務(wù),用A表示存貨量,重新執(zhí)行各操作的過(guò)程如圖7-3(a)所示。圖7-3封鎖操作的幾種情況

2.二級(jí)封鎖協(xié)議

二級(jí)封鎖協(xié)議的內(nèi)容包括:

(1)一級(jí)封鎖協(xié)議;

(2)任一事務(wù)在讀取數(shù)據(jù)(不修改)之前,必須先對(duì)其加上S鎖,讀完后即可釋放S鎖。

二級(jí)封鎖協(xié)議不但能夠防止丟失修改的結(jié)果,還可以進(jìn)一步解決讀“臟”數(shù)據(jù)問(wèn)題。但由于二級(jí)封鎖協(xié)議對(duì)數(shù)據(jù)讀完后即可釋放S鎖,故不能解決“不可重復(fù)讀”問(wèn)題。例如,圖7-3(c)所示的并發(fā)操作執(zhí)行過(guò)程遵從二級(jí)封鎖協(xié)議,但卻發(fā)生了“不可重復(fù)讀”錯(cuò)誤。

3.三級(jí)封鎖協(xié)議

三級(jí)封鎖協(xié)議的內(nèi)容包括:

(1)一級(jí)封鎖協(xié)議;

(2)任一事務(wù)在讀取數(shù)據(jù)(不修改)之前,必須先對(duì)其加上S鎖,直到事務(wù)結(jié)束才釋放這個(gè)S鎖。

由于三級(jí)封鎖協(xié)議強(qiáng)調(diào)即使事務(wù)讀完數(shù)據(jù)A之后也不釋放S鎖,從而使得其他事務(wù)無(wú)法更改數(shù)據(jù)A,因而,三級(jí)封鎖協(xié)議不但解決了丟失修改結(jié)果的問(wèn)題和讀“臟”數(shù)據(jù)問(wèn)題,而且防止了“不可重復(fù)讀”錯(cuò)誤。

1.活鎖

如果多個(gè)事務(wù)要對(duì)同一數(shù)據(jù)對(duì)象加鎖,則可能造成某些事務(wù)永遠(yuǎn)等待而得不到控制權(quán),這種現(xiàn)象稱為活鎖,又稱為餓死。例如,假定:

7.4封鎖的問(wèn)題及解決方法●?T1事務(wù)為R數(shù)據(jù)加了鎖,T2事務(wù)又請(qǐng)求為R加鎖,于是T2等待;

●?T3事務(wù)也請(qǐng)求為R加鎖,當(dāng)T1釋放了R上的鎖之后,系統(tǒng)首先批準(zhǔn)了T3的請(qǐng)求,T2仍然等待;

●?T4又請(qǐng)求為R加鎖,當(dāng)T3釋放了R上的鎖之后,系統(tǒng)又批準(zhǔn)了T4的請(qǐng)求;

……

這樣,T2可能永遠(yuǎn)等待下去。

2.死鎖

如果兩個(gè)以上事務(wù)集合中的每個(gè)事務(wù)都在等待加鎖當(dāng)前已被另一事務(wù)加鎖的數(shù)據(jù)項(xiàng),從而造成多事務(wù)交錯(cuò)等待的僵持局面,這種現(xiàn)象稱為死鎖。例如:

●如果T1和T2事務(wù)都需要R1和R2數(shù)據(jù),操作時(shí)T1為R1加了鎖,T2為R2加了鎖;

●?T1又請(qǐng)求為R2加鎖,T2又請(qǐng)求為R1加鎖;

●因T2已封鎖了R2,故T1等待T2釋放R2上的鎖。同理,因T1已封鎖了R1,故T2等待T1釋放R1上的鎖。由于T1和T2都沒(méi)有獲得全部需要的數(shù)據(jù),故都不會(huì)結(jié)束而只能繼續(xù)等待。

3.死鎖的預(yù)防

數(shù)據(jù)庫(kù)系統(tǒng)中,產(chǎn)生死鎖的原因是兩個(gè)或多個(gè)事務(wù)都為某些數(shù)據(jù)對(duì)象加了鎖,然后又都請(qǐng)求對(duì)已為其他事務(wù)加了鎖的數(shù)據(jù)對(duì)象加鎖,從而出現(xiàn)死鎖等待。防止死鎖的發(fā)生其實(shí)就是要破壞產(chǎn)生死鎖的條件。

預(yù)防死鎖通常有兩種方法。

(1)一次封鎖法:要求每個(gè)事務(wù)必須一次將所有要使用的數(shù)據(jù)全部加鎖,否則就不能繼續(xù)執(zhí)行。這種方法可以有效地防止死鎖的發(fā)生,但降低了系統(tǒng)的并發(fā)度。

(2)順序封鎖法:預(yù)先對(duì)數(shù)據(jù)對(duì)象規(guī)定一個(gè)封鎖順序,所有事務(wù)都按這個(gè)順序執(zhí)行封鎖。順序封鎖法同樣可以有效地防止死鎖,但維護(hù)眾多而且變化的資源的封鎖順序較為困難,成本較高且較難實(shí)現(xiàn)。

4.死鎖的診斷與解除

數(shù)據(jù)庫(kù)系統(tǒng)中診斷死鎖的方法與操作系統(tǒng)類似,即使用一個(gè)事務(wù)等待圖,它動(dòng)態(tài)地反映所有事務(wù)的等待狀況。并發(fā)控制子系統(tǒng)周期性地(比如每隔1分鐘)檢測(cè)事務(wù)等待圖,如果發(fā)現(xiàn)圖中存在回路,則表示系統(tǒng)中出現(xiàn)了死鎖。

一般來(lái)講,死鎖是不可避免的。DBMS的并發(fā)控制子系統(tǒng)一旦檢測(cè)到系統(tǒng)中存在死鎖,就要設(shè)法解除。通常采用的方法是選擇一個(gè)處理死鎖代價(jià)最小的事務(wù),將其撤銷,釋放此事務(wù)持有的所有的鎖,使其他事務(wù)得以繼續(xù)運(yùn)行下去。當(dāng)然,對(duì)撤銷的事務(wù)所執(zhí)行的數(shù)據(jù)修改操作必須加以恢復(fù)。

5.兩段鎖協(xié)議

可串行性是并行調(diào)度正確性的唯一準(zhǔn)則,兩段鎖協(xié)議是為保證并行調(diào)度可串行性而提供的封鎖協(xié)議。

兩段封鎖協(xié)議規(guī)定:

(1)在對(duì)任何數(shù)據(jù)進(jìn)行讀、寫(xiě)操作之前,事務(wù)首先要獲得對(duì)該數(shù)據(jù)的封鎖。

(2)在釋放一個(gè)封鎖之后,事務(wù)不再獲得任何其他封鎖。

所謂“兩段”鎖的意思是:事務(wù)分為兩個(gè)階段,第一階段是獲得封鎖,也稱為擴(kuò)展階段;第二階段是釋放封鎖,也稱為收縮階段。在一個(gè)事務(wù)中,從任何有解鎖釋放點(diǎn)的地方開(kāi)始,如果后面還發(fā)生加鎖,就違反了兩段封鎖協(xié)議。例如,假定事務(wù)1的封鎖序列是:事務(wù)2的封鎖序列是:

SlockAUnlockASlockBXlockCUnlockCUnlockB;

則事務(wù)1遵守兩段封鎖協(xié)議,而事務(wù)2不遵守兩段封鎖協(xié)議。

如果并行執(zhí)行的所有事務(wù)都遵守兩段鎖協(xié)議,則對(duì)這些事務(wù)的所有并行調(diào)度策略都是可串行化的。因此得出結(jié)論:所有遵守兩段鎖協(xié)議的事務(wù),其并行的結(jié)果一定是正確的。

應(yīng)該注意的是:事務(wù)遵守兩段鎖協(xié)議是可串行化調(diào)度的充分條件,而不是必要條件。也就是說(shuō),可串行化的調(diào)度中,不一定所有事務(wù)都必須符合兩段封鎖協(xié)議。

6.鎖的粒度與鎖升級(jí)

關(guān)系數(shù)據(jù)庫(kù)中,加鎖的對(duì)象可以是整個(gè)數(shù)據(jù)庫(kù),也可以是一個(gè)關(guān)系、一個(gè)元組甚至是一個(gè)元組的幾個(gè)屬性值。加鎖對(duì)象還可以是一些物理單元,如頁(yè)(數(shù)據(jù)頁(yè)或索引項(xiàng))、塊等。鎖的粒度(Granularity)指的是加鎖對(duì)象的大小。鎖粒度與系統(tǒng)的并發(fā)度和并發(fā)控制的開(kāi)銷密切相關(guān)。鎖粒度越小,并發(fā)度越高,系統(tǒng)開(kāi)銷也越大;鎖粒度越大,并發(fā)度越低,系統(tǒng)開(kāi)銷也越小。7.5.1數(shù)據(jù)庫(kù)故障的種類

1.事務(wù)內(nèi)部故障

事務(wù)程序可以發(fā)現(xiàn)某些事務(wù)內(nèi)部故障,但仍有許多非預(yù)期(未預(yù)先置入程序)故障,如運(yùn)算溢出、違反了某些完整性限制,以及在并發(fā)執(zhí)行時(shí)發(fā)生死鎖而需要撤銷的事務(wù)等,往往不能被事務(wù)處理程序本身發(fā)現(xiàn)。7.5數(shù)據(jù)庫(kù)恢復(fù)技術(shù)

2.系統(tǒng)故障

系統(tǒng)故障是指那些造成系統(tǒng)停止運(yùn)轉(zhuǎn)而需要重新啟動(dòng)系統(tǒng)的事件,如突然停電、CPU故障、操作系統(tǒng)故障、DBMS代碼錯(cuò)誤、數(shù)據(jù)庫(kù)服務(wù)器出錯(cuò)以及某種誤操作等。這類故障影響正在運(yùn)行的所有事務(wù),但并未破壞數(shù)據(jù)庫(kù)。這時(shí)候,內(nèi)存中的內(nèi)容,尤其是數(shù)據(jù)庫(kù)緩沖區(qū)中的內(nèi)容都會(huì)丟失,所有事務(wù)都會(huì)非正常終止。系統(tǒng)故障主要有兩種情況:

一是發(fā)生故障時(shí),某些尚未完成的事務(wù)的部分結(jié)果已送入物理數(shù)據(jù)庫(kù),可能會(huì)使得數(shù)據(jù)庫(kù)處于不正確狀態(tài)。為了保證數(shù)據(jù)一致性,需要清除這些事務(wù)對(duì)數(shù)據(jù)庫(kù)的修改。因而,恢復(fù)子系統(tǒng)必須在系統(tǒng)重新啟動(dòng)時(shí)讓非正常終止的事務(wù)回滾,強(qiáng)行撤銷(UNDO)那些未完成的事務(wù)。

二是發(fā)生故障時(shí),有些已完成的事務(wù)的部分或者全部因尚未寫(xiě)入磁盤(pán)上的物理數(shù)據(jù)庫(kù)而滯留在緩沖區(qū),故障使得這些事務(wù)對(duì)數(shù)據(jù)庫(kù)的修改部分或全部丟失,這也會(huì)使數(shù)據(jù)庫(kù)處于不一致?tīng)顟B(tài)。因此,應(yīng)將這些事務(wù)已提交的結(jié)果重新寫(xiě)入數(shù)據(jù)庫(kù)。這就要求系統(tǒng)重新啟動(dòng)后,恢復(fù)子系統(tǒng)在撤銷所有未完成事務(wù)之外,還需要重做(REDO)那些已提交的事務(wù),使得數(shù)據(jù)庫(kù)真正恢復(fù)到一致?tīng)顟B(tài)。

3.介質(zhì)故障

介質(zhì)故障指的是外存儲(chǔ)器的故障,如磁盤(pán)損壞、磁頭碰撞、瞬時(shí)磁場(chǎng)干擾等,這些是與前兩種故障(軟故障)不同的硬故障。這類故障會(huì)破壞數(shù)據(jù)庫(kù)或部分?jǐn)?shù)據(jù),并影響正在存取這部分?jǐn)?shù)據(jù)的那些事務(wù)。

介質(zhì)故障發(fā)生的可能性較小,但其破壞作用卻是最大的,可能會(huì)使得數(shù)據(jù)無(wú)法恢復(fù)。解決的辦法是及時(shí)進(jìn)行系統(tǒng)備份并且定期進(jìn)行維護(hù)。

4.計(jì)算機(jī)病毒

計(jì)算機(jī)病毒是具有破壞作用的程序,這種程序可以破壞數(shù)據(jù)、占用計(jì)算機(jī)軟件或硬件資源、妨礙計(jì)算機(jī)系統(tǒng)的正常運(yùn)行并且通過(guò)極強(qiáng)的自我復(fù)制功能而快速“傳染”給其他應(yīng)用程序或計(jì)算機(jī)系統(tǒng),使得包括數(shù)據(jù)庫(kù)系統(tǒng)在內(nèi)的計(jì)算機(jī)系統(tǒng)無(wú)法正常工作。因此,重要的數(shù)據(jù)庫(kù)系統(tǒng)應(yīng)該十分重視計(jì)算機(jī)病毒的預(yù)防和清除工作。

5.用戶操作錯(cuò)誤

有時(shí)候,用戶有意或無(wú)意的操作也可能刪除數(shù)據(jù)庫(kù)中的有用數(shù)據(jù)、加入錯(cuò)誤數(shù)據(jù)或者造成系統(tǒng)無(wú)法正常工作,這需要通過(guò)技術(shù)(如用戶、權(quán)限管理等)、培訓(xùn)以及人事制度上的綜合治理來(lái)加以保證。7.5.2數(shù)據(jù)庫(kù)恢復(fù)技術(shù)

1.?dāng)?shù)據(jù)轉(zhuǎn)儲(chǔ)法

DBA應(yīng)該根據(jù)數(shù)據(jù)庫(kù)使用情況確定適當(dāng)?shù)霓D(zhuǎn)儲(chǔ)周期和轉(zhuǎn)儲(chǔ)策略。根據(jù)轉(zhuǎn)儲(chǔ)時(shí)系統(tǒng)狀態(tài)的不同,可將轉(zhuǎn)儲(chǔ)分為靜態(tài)轉(zhuǎn)儲(chǔ)和動(dòng)態(tài)轉(zhuǎn)儲(chǔ)兩種。

靜態(tài)轉(zhuǎn)儲(chǔ)是指在轉(zhuǎn)儲(chǔ)過(guò)程中,系統(tǒng)不運(yùn)行其他事務(wù)而專門進(jìn)行數(shù)據(jù)轉(zhuǎn)儲(chǔ)工作。靜態(tài)轉(zhuǎn)儲(chǔ)操作開(kāi)始時(shí),數(shù)據(jù)庫(kù)處于一致?tīng)顟B(tài),轉(zhuǎn)儲(chǔ)期間不允許其他事務(wù)對(duì)數(shù)據(jù)庫(kù)進(jìn)行任何存取、修改操作,數(shù)據(jù)庫(kù)仍處于一致?tīng)顟B(tài)。靜態(tài)轉(zhuǎn)儲(chǔ)雖然簡(jiǎn)單,并且能夠得到一個(gè)數(shù)據(jù)一致的副本,但這種轉(zhuǎn)儲(chǔ)必須等待正在運(yùn)行的事務(wù)結(jié)束后才能進(jìn)行,新的事務(wù)也必須等待轉(zhuǎn)儲(chǔ)結(jié)束后才能執(zhí)行,降低了數(shù)據(jù)庫(kù)的可用性。動(dòng)態(tài)轉(zhuǎn)儲(chǔ)是指在轉(zhuǎn)儲(chǔ)過(guò)程中允許其他事務(wù)對(duì)數(shù)據(jù)庫(kù)進(jìn)行存取或修改操作的轉(zhuǎn)儲(chǔ)方式。也就是說(shuō),轉(zhuǎn)儲(chǔ)和用戶事務(wù)并發(fā)執(zhí)行。動(dòng)態(tài)轉(zhuǎn)儲(chǔ)時(shí)不必等待正在運(yùn)行的事務(wù)結(jié)束,也不會(huì)影響新事務(wù)開(kāi)始,其主要缺點(diǎn)是后備副本中的數(shù)據(jù)并不總是正確有效的。由于動(dòng)態(tài)轉(zhuǎn)儲(chǔ)是動(dòng)態(tài)進(jìn)行的,后備副本中存儲(chǔ)的可能是過(guò)時(shí)的數(shù)據(jù)。因此,有必要將轉(zhuǎn)儲(chǔ)期間各事務(wù)對(duì)數(shù)據(jù)庫(kù)的修改活動(dòng)登記下來(lái),建立日志文件,使得通過(guò)后備副本和日志文件可將數(shù)據(jù)庫(kù)恢復(fù)到某一時(shí)刻的正確狀態(tài)。轉(zhuǎn)儲(chǔ)還可以分為海量轉(zhuǎn)儲(chǔ)和增量轉(zhuǎn)儲(chǔ)兩種,海量轉(zhuǎn)儲(chǔ)是指每次轉(zhuǎn)儲(chǔ)全部數(shù)據(jù)庫(kù)。這種轉(zhuǎn)儲(chǔ)方式可以得到后備副本并用之于方便地進(jìn)行數(shù)據(jù)恢復(fù)工作。如果數(shù)據(jù)庫(kù)中的數(shù)據(jù)量大且更新頻率高,則不適合頻繁地海量轉(zhuǎn)儲(chǔ)。增量轉(zhuǎn)儲(chǔ)是指每次只轉(zhuǎn)儲(chǔ)上一次轉(zhuǎn)儲(chǔ)后更新過(guò)的數(shù)據(jù),適用于數(shù)據(jù)庫(kù)較大但事務(wù)處理卻十分頻繁的數(shù)據(jù)庫(kù)系統(tǒng)。

由于數(shù)據(jù)轉(zhuǎn)儲(chǔ)可在動(dòng)態(tài)和靜態(tài)兩種狀態(tài)下進(jìn)行,因此數(shù)據(jù)轉(zhuǎn)儲(chǔ)方法可以分為4類:動(dòng)態(tài)海量轉(zhuǎn)儲(chǔ)、動(dòng)態(tài)增量轉(zhuǎn)儲(chǔ)、靜態(tài)海量轉(zhuǎn)儲(chǔ)和靜態(tài)增量轉(zhuǎn)儲(chǔ)。

2.日志文件的內(nèi)容

不同數(shù)據(jù)庫(kù)系統(tǒng)的日志文件格式不完全相同。日志文件主要有以記錄為單位的日志文件和以數(shù)據(jù)塊為單位的日志文件。

以記錄為單位的日志文件中需要登記的內(nèi)容包括每個(gè)事務(wù)的開(kāi)始(BEGINTRANSACTION)標(biāo)記、結(jié)束(COMMIT或ROLLBACK)標(biāo)記和所有更新操作,這些內(nèi)容均作為日志文件中的一個(gè)日志記錄(LogRecord)。對(duì)于更新操作的日志記錄,其內(nèi)容主要包括事務(wù)標(biāo)識(shí)(表明是哪個(gè)事務(wù))、操作的類型(插入、刪除或修改)、操作對(duì)象(記錄內(nèi)部標(biāo)識(shí))、更新前數(shù)據(jù)的舊值(插入操作,該項(xiàng)為空)及更新后數(shù)據(jù)的新值(刪除操作,該項(xiàng)為空)。以數(shù)據(jù)塊為單位的日志文件內(nèi)容包括事務(wù)標(biāo)識(shí)和更新的數(shù)據(jù)塊。由于更新前后的各數(shù)據(jù)塊都放入了日志文件,所以操作的類型和操作對(duì)象等信息就不必放入日志記錄。

3.日志文件法

日志文件可用于事務(wù)故障恢復(fù)、系統(tǒng)故障恢復(fù)以及協(xié)助后備副本進(jìn)行介質(zhì)故障恢復(fù)。如果數(shù)據(jù)庫(kù)文件被損毀,則可重新裝入后備副本而將數(shù)據(jù)庫(kù)恢復(fù)到轉(zhuǎn)儲(chǔ)結(jié)束時(shí)的正確狀態(tài),再通過(guò)建立的日志文件,重新執(zhí)行已完成的事務(wù)并撤銷故障發(fā)生時(shí)尚未完成的事務(wù)。這樣,不必運(yùn)行應(yīng)用程序即可將數(shù)據(jù)庫(kù)恢復(fù)到故障前某一時(shí)刻的正確狀態(tài)。

為了保證數(shù)據(jù)庫(kù)的可恢復(fù)性,登記日志文件時(shí)必須遵循兩條原則:一是嚴(yán)格按照事務(wù)執(zhí)行的時(shí)間次序登記;二是先寫(xiě)日志文件再寫(xiě)數(shù)據(jù)庫(kù)。將修改數(shù)據(jù)的結(jié)果寫(xiě)入數(shù)據(jù)庫(kù)與將描述本次修改的日志記錄寫(xiě)入日志文件是兩種不同的寫(xiě)操作。如果這兩種寫(xiě)操作只完成了一個(gè),則有可能發(fā)生故障:

●如果先寫(xiě)數(shù)據(jù)庫(kù)修改結(jié)果而未在運(yùn)行記錄中登記,則以后無(wú)法恢復(fù)這個(gè)修改結(jié)果。

●如果先寫(xiě)日志而未修改數(shù)據(jù)庫(kù),則按日志文件恢復(fù)時(shí)只是多執(zhí)行一次不必要的UNDO操作,并不影響數(shù)據(jù)庫(kù)的正確性。

可見(jiàn),先寫(xiě)日志文件而后進(jìn)行數(shù)據(jù)庫(kù)的更新操作是比較安全的。7.5.3數(shù)據(jù)庫(kù)恢復(fù)方法

1.發(fā)生事務(wù)故障時(shí)的恢復(fù)方法

如果某個(gè)事務(wù)執(zhí)行過(guò)程中發(fā)生了故障,則恢復(fù)子系統(tǒng)可以通過(guò)日志文件撤銷(UNDO)該事務(wù)對(duì)數(shù)據(jù)庫(kù)已經(jīng)做出的修改結(jié)果。這個(gè)工作是按照以下步驟進(jìn)行的:

(1)反向(從后往前)掃描文件日志,查找該事務(wù)的更新操作。

(2)如果找到的是該事務(wù)的起始記錄,則UNDO結(jié)束;否則,對(duì)該事務(wù)的更新操作執(zhí)行逆操作,即將日志記錄中“更新前的值”寫(xiě)入數(shù)據(jù)庫(kù)。

●如果記錄中是插入操作,則相當(dāng)于做刪除操作。

●如果記錄中是刪除操作,則做插入操作。

●如果是修改操作,則相當(dāng)于用修改前的值替代修改后的值。

(3)重復(fù)執(zhí)行(1)和(2),恢復(fù)該事務(wù)的其他更新操作,直至讀到該事務(wù)的開(kāi)始標(biāo)記為止,該事務(wù)的故障恢復(fù)工作才能完成。

事務(wù)故障的恢復(fù)通常是由系統(tǒng)自動(dòng)完成的,用戶并不知曉系統(tǒng)是如何進(jìn)行的。

2.發(fā)生系統(tǒng)故障時(shí)的恢復(fù)方法

系統(tǒng)的恢復(fù)是按照以下步驟進(jìn)行的:

(1)正向(從頭到尾)掃描日志文件,找出那些故障發(fā)生前已經(jīng)提交的事務(wù),將其事務(wù)標(biāo)記記入重新執(zhí)行(REDO)的隊(duì)列。同時(shí)找出故障發(fā)生時(shí)尚未完成的事務(wù),將其事務(wù)標(biāo)記記入撤銷(UNDO)隊(duì)列。

注:已提交事務(wù)既有BEGINTRANSACTION記錄,也有COMMIT或ROLLBACK記錄;未完成事務(wù)只有BEGINTRANSACTION記錄而無(wú)相應(yīng)的COMMIT或ROLLBACK記錄。

(2)對(duì)撤銷隊(duì)列中的各個(gè)事務(wù)進(jìn)行撤銷(UNDO)處理。方法是:反向掃描日志文件,對(duì)每個(gè)事務(wù)的更新操作執(zhí)行逆操作,即將日志記錄中“更新前的值”寫(xiě)入數(shù)據(jù)庫(kù)。

(3)對(duì)重新執(zhí)行隊(duì)列中的各個(gè)事務(wù)進(jìn)行重新執(zhí)行(REDO)處理。方法是:正向掃描日志文件,對(duì)每個(gè)重新執(zhí)行的事務(wù)重新執(zhí)行日志文件登記操作,即將日志記錄中“更新后的值”寫(xiě)入數(shù)據(jù)庫(kù)。

3.發(fā)生介質(zhì)故障時(shí)的恢復(fù)方法

介質(zhì)發(fā)生故障時(shí),磁盤(pán)上的物理數(shù)據(jù)庫(kù)和日志文件都可能遭到破壞,這時(shí)的恢復(fù)工作最麻煩,必須重裝最新的數(shù)據(jù)庫(kù)后備副本,重新執(zhí)行該副本到發(fā)生故障之間完成的那些事務(wù)(對(duì)靜態(tài)轉(zhuǎn)儲(chǔ)而言)。恢復(fù)步驟為:

(1)恢復(fù)系統(tǒng),必要時(shí)還要更新介質(zhì)(磁盤(pán)等)。

(2)如果操作系統(tǒng)或者DBMS崩潰,則需要重新啟動(dòng)系統(tǒng)。

(3)裝入最新的數(shù)據(jù)庫(kù)后備副本,使數(shù)據(jù)庫(kù)恢復(fù)到最近一次轉(zhuǎn)儲(chǔ)時(shí)的一致性狀態(tài)。對(duì)于動(dòng)態(tài)轉(zhuǎn)儲(chǔ)的數(shù)據(jù)庫(kù)副本,還需要同時(shí)裝入轉(zhuǎn)儲(chǔ)開(kāi)始時(shí)刻的日志文件副本。利用恢復(fù)系統(tǒng)故障的方法(重做?+?撤銷),才能將數(shù)據(jù)庫(kù)恢復(fù)到一致性狀態(tài)。

(4)裝入轉(zhuǎn)儲(chǔ)結(jié)束時(shí)刻的日志文件副本。

(5)掃描日志文件,找出故障發(fā)生時(shí)提交的事務(wù),加入REDO隊(duì)列。

(6)重新執(zhí)行REDO隊(duì)列中的事務(wù)。

通過(guò)日志文件法進(jìn)行數(shù)據(jù)庫(kù)恢復(fù)時(shí),恢復(fù)子系統(tǒng)必須搜索所有的日志來(lái)確定哪些事務(wù)需要重新執(zhí)行。

1.實(shí)驗(yàn)任務(wù)與目的

(1)在SQLServer的查詢編輯器中編寫(xiě)代碼,在單個(gè)批處理中實(shí)現(xiàn)一個(gè)事務(wù)。了解事務(wù)的概念以及事務(wù)與批處理的關(guān)系。

(2)在SQLServerManagementStudio中創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)的完整備份,再還原該數(shù)據(jù)庫(kù)。掌握創(chuàng)建和和使用數(shù)據(jù)庫(kù)備份的方法。實(shí)驗(yàn)7事務(wù)管理與數(shù)據(jù)庫(kù)備份

2.預(yù)備知識(shí)

(1)本實(shí)驗(yàn)涉及本章中以下內(nèi)容:

●事務(wù)的概念、基本特征以及基本操作方法。

●?SQLServer中的事務(wù)以及批處理的語(yǔ)法。

●封鎖機(jī)制的概念以及死鎖的診斷方法。

●數(shù)據(jù)庫(kù)故障的種類以及數(shù)據(jù)庫(kù)恢復(fù)技術(shù)的知識(shí)。

(2)?SQLServer鎖的類型及其控制。

SQLServer的基本鎖是S(共享)鎖和X(排他)鎖。基本鎖之外還有三種鎖:意向鎖、修改鎖和模式鎖,這幾種鎖由SQLServer系統(tǒng)自動(dòng)控制。

SQLServer一般都會(huì)自動(dòng)提供加鎖功能,例如:

●在SELECT語(yǔ)句訪問(wèn)數(shù)據(jù)庫(kù)時(shí),系統(tǒng)自動(dòng)使用共享鎖訪問(wèn)數(shù)據(jù);使用INSERT、DELETE和UPDATE語(yǔ)句添加、修改和刪除數(shù)據(jù)時(shí),系統(tǒng)自動(dòng)為所使用的數(shù)據(jù)加上排他鎖。

●系統(tǒng)用意向鎖將鎖分別按行級(jí)鎖層、頁(yè)級(jí)鎖層和表級(jí)鎖層設(shè)置,使得多個(gè)鎖之間的沖突最小化。

●在系統(tǒng)修改一個(gè)頁(yè)(內(nèi)存中固定大小的一塊數(shù)據(jù),常與外存中一個(gè)扇區(qū)大小相同)時(shí),自動(dòng)加修改鎖(與共享鎖兼容),修改過(guò)后上升為排他鎖。

●在操作涉及到引用表或索引時(shí),自動(dòng)提供模式鎖(鎖住正在使用的表等對(duì)象的結(jié)構(gòu))和修改鎖(通知其他用戶當(dāng)前用戶正在修改數(shù)據(jù))。

SQLServer自動(dòng)使用與任務(wù)相應(yīng)的等級(jí)鎖來(lái)鎖定資源對(duì)象,以使鎖的成本最小化。用戶對(duì)鎖機(jī)制有所了解即可,使用時(shí)不涉及鎖的操作??梢哉J(rèn)為SQLServer的封鎖機(jī)制對(duì)用戶是透明的。

(3)死鎖原理與SQLServer中的排查。

計(jì)算機(jī)操作系統(tǒng)中將死鎖定義為:一級(jí)進(jìn)程中的各個(gè)進(jìn)程均占有不會(huì)釋放的資源,但因互相申請(qǐng)被其他進(jìn)程占用而不會(huì)釋放的資源,從而形成的一種永久等待狀態(tài)。SQLServer中,如果兩個(gè)或兩個(gè)以上任務(wù)都鎖定了其他任務(wù)試圖鎖定的資源,則會(huì)造成這些任務(wù)永久阻塞,從而出現(xiàn)死鎖。

使用SQLServer的存儲(chǔ)過(guò)程sp_who查看數(shù)據(jù)庫(kù)里的活動(dòng)用戶和進(jìn)程的情況;使用sp_lock查看當(dāng)前數(shù)據(jù)庫(kù)中鎖的情況,通過(guò)objectID(@objID)還可以查看哪個(gè)資源被鎖。

SQLServer內(nèi)部有一個(gè)鎖監(jiān)視器線程執(zhí)行死鎖檢查,鎖監(jiān)視器對(duì)特定線程啟動(dòng)死鎖檢查時(shí),標(biāo)識(shí)線程正在等待的資源,然后查找特定資源的所有者并遞歸地繼續(xù)執(zhí)行對(duì)那些線程的死鎖搜索,直到找到一個(gè)構(gòu)成死鎖條件的循環(huán)。檢測(cè)到死鎖后,數(shù)據(jù)庫(kù)引擎選擇一個(gè)回滾時(shí)開(kāi)銷最小的事務(wù)進(jìn)行回滾并釋放該事務(wù)持有的所有鎖,使得其他線程的事務(wù)可以請(qǐng)求資源并繼續(xù)運(yùn)行。實(shí)驗(yàn)7.1實(shí)現(xiàn)事務(wù)

1.編輯創(chuàng)建事務(wù)的代碼

在SQLServerManagementStudio中,展開(kāi)dbCourses數(shù)據(jù)庫(kù)所在的服務(wù)器結(jié)點(diǎn),再展開(kāi)其中的“數(shù)據(jù)庫(kù)”結(jié)點(diǎn),選定dbCourses結(jié)點(diǎn);單擊工具欄上的“新建查詢”按鈕,打開(kāi)查詢編輯器窗口并在其中輸入以下代碼:

BEGINTRANSACTION

INSERTINTO班級(jí)(班號(hào),班名,專業(yè)號(hào),人數(shù))

VALUES('20123001','應(yīng)數(shù)21','68',28)

IF@@ERROR=0BEGIN

PRINT'班級(jí)表中插入了一條記錄'

UPDATE學(xué)生

SET班號(hào)='20123001'

WHERE班號(hào)='12345678'

DELETE專業(yè)

WHERE學(xué)院號(hào)='19'

COMMITTRANSACTIONEND

ELSEBEGIN

PRINT'班級(jí)表中插入記錄失敗,回滾事務(wù)'

ROLLBACKTRANSACTION

END

2.執(zhí)行事務(wù)

單擊!按鈕執(zhí)行這一段程序,如果發(fā)生錯(cuò)誤,據(jù)此修改數(shù)據(jù)庫(kù)中相應(yīng)數(shù)據(jù),直到運(yùn)行通過(guò)為止。實(shí)驗(yàn)7.2檢測(cè)死鎖

1.編輯創(chuàng)建兩個(gè)表的代碼

在SQLServerManagementStudio中,展開(kāi)服務(wù)器結(jié)點(diǎn),再展開(kāi)其中的“數(shù)據(jù)庫(kù)”結(jié)點(diǎn),選定某個(gè)數(shù)據(jù)庫(kù)結(jié)點(diǎn);單擊工具欄上的“新建查詢”按鈕,打開(kāi)查詢編輯器窗口并在其中輸入以下代碼:

usedbCourses

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論