FB/IB多代事务结构详解--对FB事务最好的讲解
生活随笔
收集整理的這篇文章主要介紹了
FB/IB多代事务结构详解--对FB事务最好的讲解
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
近來,接到很多人詢問InterBase的事務處理問題。我在以前文章的基礎上重新加以整理,寫了這個說明InterBase事物處理的短文,希望對大家有所幫助。此外,我希望唐版主能把這個短文做成一個單獨文件連接,便于大家查閱,謝謝。
InterBase的事務管理
我們知道,與其它關(guān)系數(shù)據(jù)庫系統(tǒng)不同,InterBase采用獨特的多代結(jié)構(gòu)和版本事務來提高其性能,因此,對InterBase來說,事務就顯得尤其重要。為保證其版本事務的工作,InterBase要求任何一個對數(shù)據(jù)庫的訪問都必須包含在一個事務中進行,也就是說,無論對數(shù)據(jù)庫進行讀select、插入insert、更改update還是刪除delete都要先啟動一個事務,然后進行操作,操作完畢,結(jié)束事務。你不可能在沒有事務的情況下對數(shù)據(jù)庫進行操作。有的關(guān)系數(shù)據(jù)庫系統(tǒng)可能在讀操作下并不啟動事務,只有在改寫情況下才啟動事務,然而InterBase卻不同,你對此必須有清醒地認識。
我們?nèi)粘>幊?#xff0c;通常使用已經(jīng)編寫好的控件,這些控件如IBX、DBExpress已經(jīng)包含了事務處理的代碼,但是在底層,歸根結(jié)底都是通過InterBase的API函數(shù)進行的。
在InterBas的API函數(shù)中,事務處理常用的API函數(shù)有:
1、isc_start_transaction():使用已經(jīng)定義的TPB(事務參數(shù)緩存)在一個或多個數(shù)據(jù)庫上啟動一個新的事務。
2、isc_commit_retaining():提交事務的更改,但并不結(jié)束事務的執(zhí)行,仍然保留事務的上下文,可以再使用。
3、isc_commit_transaction():提交事務的更改,并結(jié)束事務的執(zhí)行,釋放上下文。
4、isc_rollback_transaction():回退事務的更改,并結(jié)束事務的執(zhí)行,釋放上下文。
啟動一個事務分為三個步驟:創(chuàng)建并初始化事務句柄,可選擇的創(chuàng)建并配置事務參數(shù)緩存,最后調(diào)用isc_start_transaction()。處理事務的永恒不變的原則是:任何事務都要盡可能地及時結(jié)束,不要拖延。
這里我想強調(diào)一點,那就是InterBase的事務啟動方式。通常情況下,對程序員和用戶來說InterBase事務有兩種啟動方式,隱含啟動和顯式啟動。大多數(shù)情況下大多數(shù)的程序員采用的是隱含啟動,也就是你并沒有明確調(diào)用(直接或間接)事務處理函數(shù)來處理事務,此時則由InterBase自動為你做這些工作。然而采用顯示的事務處理應該說是一種好的、值得推薦的方法,這可以有效地配合InterBase的多代結(jié)構(gòu)工作。當然顯示事務啟動需要自行調(diào)用(直接或間接)事務處理的函數(shù),就得多寫幾行代碼。
有些人不理解,既然InterBase能在你不顯式處理事務的情況下自動幫你處理,那還要我自己處理事務干什么?答案是:機器永遠沒有人聰明!它有時不知道應該及時結(jié)束一個事務!尤其在我們使用像IBX、DBExpress這樣的控件的時候,它們對事務的自動處理并不是盡善盡美的。
下面我們來了解一下事務參數(shù)緩存TPB。TPB對事務的執(zhí)行有著至關(guān)重要的影響。甚至可以毫不夸張的說,搞懂了TPB,也就搞懂了InterBase事務處理。然而,我們經(jīng)常使用的IBX、DBExpress等組件在底層封裝了事務處理API函數(shù),讓很多人不能明顯地(至少可以說不能像了解其他屬性那樣)了解TPB的含義。
TPB參數(shù)可分為如下幾類:
1、事務版本號:isc_tpb_version3,InterBase引擎內(nèi)部使用,表明事務的版本號。必須是TPB的第一個參數(shù)。
2、訪問模式:指明事務可以對數(shù)據(jù)表進行的操作。有isc_tpb_read、isc_tpb_write兩個選項。
1)isc_tpb_write:允許對表進行讀寫(select,insert,update,delete)操作,為缺省的訪問模式。
2)isc_tpb_read:只允許對表進行讀(select)操作。
只能設定一種訪問模式,否則后者將覆蓋前者。如果不指定,則使用缺省值。
3、事務之間的隔離級別:表明并發(fā)的事務間相互隔離的程度,也可以說是相互不受影響的程度。注意這里強調(diào)的是并發(fā)的事務。如果不是并發(fā)事務,則相互之間不會存在沖突,也就不需要進行相互間的隔離。事務的隔離級別通常有三級,分別是:
·read
dirty臟讀
·read committed提交讀
·consistency一致性
read
dirty臟讀是最低的隔離級別,它允許一個事務訪問另一個并發(fā)事務所作的還沒有提交的更改。由于這個隔離級別可以讀到其他事務未提交的數(shù)據(jù)或者不完整的數(shù)據(jù),因此可能造成數(shù)據(jù)的不一致性,所以在關(guān)系型數(shù)據(jù)庫系統(tǒng)中通常不被推薦。雖然從理論上講InterBase的多代結(jié)構(gòu)可以支持該選項,但實際上InterBase并不接受臟讀,因此實際中不要使用這個選項。BDE支持read
dirty。
因此InterBase只有有下列四個隔離選項:
isc_tpb_read_committed,
isc_tpb_rec_version
isc_tpb_read_committed,
isc_tpb_no_rec_version
isc_tpb_concurrency
isc_tpb_consistency
實際是三個隔離級別,由低到高分別是:
isc_tpb_read_committed
isc_tpb_concurrency
isc_tpb_consistency
顯然,隔離級別越高,并發(fā)性能越低。
1)isc_tpb_read_commited:這是InterBase中支持的最低隔離級別。它只允許一個事務訪問其他并發(fā)事務已經(jīng)提交的更改,沒有提交的更改即臟數(shù)據(jù)則不允許讀取。該選項可以充分發(fā)揮InterBase的多代結(jié)構(gòu)優(yōu)勢,提供高吞吐、高并發(fā)的性能。該隔離級別必須和其他兩個選項isc_tpb_rec_version、isc_tpb_no_rec_version之一配合使用。它們提供了對已提交更改更精細的訪問控制。
·isc_tpb_read_commited,isc_tpb_no_rec_version是缺省的調(diào)優(yōu)選項,表示事務只能讀取數(shù)據(jù)行的最新版本,如果該數(shù)據(jù)行的某個更改處于掛起狀態(tài)即還沒有提交,則不能被讀取。也就是說如果數(shù)據(jù)行的所有版本已全部提交,則該選項可以訪問到已經(jīng)提交的最新版本,但如果數(shù)據(jù)行還有未提交的版本,則不允許訪問該數(shù)據(jù)行,就連已提交的版本也不能讀取。如果使用isc_tpb_wait選項,那么此時事務只能等待其他事務提交或者回退這些未提交的版本數(shù)據(jù);如果使用isc_tpb_nowait選項,那么此時事務不會等待而是立即返回一個沖突錯誤。
·
isc_tpb_read_commited,isc_tpb_rec_version則表示事務可以立即讀取已提交的數(shù)據(jù)行最新版本,盡管該數(shù)據(jù)行最近還有多個掛起的未提交版本。也就是說,不管數(shù)據(jù)行是否存在未提交的版本,該選項總是可以讀到已提交的最新版本。這種情況下可能會產(chǎn)生沖突,要小心使用。
isc_tpb_read_commited選項特別適合用于和用戶交互的在線事務處理系統(tǒng)。
2)isc_tpb_concurrency:這是比read
committed高一級的隔離,相當于Snapshot,在BDE中又叫作重復讀Repeatable Read。
它允許一個事務獲得該事務啟動時數(shù)據(jù)庫的一個快照,此后,它只能看到自身對數(shù)據(jù)庫的更改,而其他并發(fā)事務的任何更改它均無法看到(這意味著這種隔離級別并不限制其他并發(fā)事務對數(shù)據(jù)庫的改寫,只是這些改寫看不到罷了)。由于要保持事務啟動時數(shù)據(jù)庫的一個快照,所以事務啟動時數(shù)據(jù)庫中記錄的所有版本必須也保持不變,這就必須禁止垃圾收集的運行。可見這個選項很適合于報表應用程序,因為無論重復幾次讀取表中的數(shù)據(jù)它總能獲得相同的數(shù)值。和其他關(guān)系數(shù)據(jù)庫系統(tǒng)不同,這個選項既提供了良好的重復讀功能(較長的讀事務),又不影響其他用戶事務的并發(fā)在線操作(如更改),充分發(fā)揮了InterBase的多代結(jié)構(gòu)優(yōu)勢,提供高吞吐、高并發(fā)的性能。該選項不大被推薦用來和用戶進行交互,因為用戶往往需要的是實時的數(shù)據(jù)而不是好像“凍住”了的數(shù)據(jù)。此外使用該選項的事務一定要盡快結(jié)束,不能拖很長時間。
3)isc_tpb_consistency:這是最嚴格的隔離級別,相當于強制重復讀Forced
Repeatable
Read,這也是InterBase特有的隔離級別,其他關(guān)系數(shù)據(jù)庫系統(tǒng)和BDE并不支持這種級別。在這種隔離模式下,如果一個表正被一個事務訪問,則不允許其他任何事務再對其進行改寫,即相當于在表上加了一把寫鎖。該選項一定要小心使用,因為它會極大地降低并發(fā)性能,并且一旦使用則一定要在操作完成后盡快結(jié)束事務。
隔離級別也只能設定一種,否則后者將覆蓋前者。
不隔離級別的事務之間的交互如下表:
各種事務隔離級別的對比如下表:
API
level constants & IBO. Language level & tools. BDE level.
(Not
supported) (Not supported) Dirty Read
Read Committed Read Committed Read
Committed
Concurrency Snapshot Repeatable Read
Consistency Snapshot table
stability (Not
supported)
4、鎖沖突的解決方案:表明當一個事務在寫操作(更該、刪除)期間遇到訪問沖突時將如何處理。
isc_tpb_wait是缺省的方式,表示事務必須要等待,直到其他并發(fā)事務結(jié)束,鎖定的資源被釋放。一旦資源被釋放,事務就重新嘗試其操作。
isc_tpb_nowait則表示事務只是返回一個沖突錯誤而不等待資源釋放,故此時事務不會再作嘗試。
這兩種方式也只能指定其中一種,否則后者將覆蓋前者。
5、表的保留方式:通常,事務只有在真正從數(shù)據(jù)表中讀無數(shù)據(jù)或往表中寫入數(shù)據(jù)時才獲得特定的訪問權(quán)。表的保留選項則表明了對事務訪問的特定表的訪問模式和鎖的解決方式。當這個選項被使用的時候,那么當事務啟動時,這個表就被保留著某種特定的訪問權(quán)限,而不是在表實際被訪問時。該選項在多個并發(fā)事務共享數(shù)據(jù)庫訪問的環(huán)境中才有用,它有如下三個主要目的:
·防止通常情況下的死鎖和更該沖突。
·由于觸發(fā)器和約束可能影響表的鎖,因此該選項可以提供依賴鎖。盡管沒有必要提供一個明顯的依賴鎖,但它能確保由于間接的表沖突而不產(chǎn)生更該沖突。
·可以在事務中改變對一個或多個單獨的表的訪問級別。
有效的保留方式有:
1)isc_tpb_shared
,isc_tpb_lock_write:允許使用isc_tpb_write訪問模式+
isc_tpb_concurrency或+isc_tpb_read_commited隔離級別的任何事務進行更改,而使用上述隔離級別+isc_tpb_read的事務可以讀取數(shù)據(jù)。
2)isc_tpb_shared
,isc_tpb_lock_read:可以允許任何事務讀取數(shù)據(jù),也允許使用isc_tpb_write訪問模式的事務更改數(shù)據(jù)。這是最自由的保留模式。
3)isc_tpb_protected,isc_tpb_lock_write:阻止其他事務更改。使用isc_tpb_concurrency或isc_tpb_read_commited隔離級別的可以讀取數(shù)據(jù),同時也只有這些事務可以更改數(shù)據(jù)。
4)isc_tpb_protected,isc_tpb_lock_read:禁止所有的事務更改數(shù)據(jù),同時允許所有的事務讀取數(shù)據(jù)。
TPB的格式如下:
版本號
訪問模式
隔離級別
沖突解決
表保留選項
例如1:
isc_tpb_version3,
isc_tpb_write,
isc_tpb_concurrency,
isc_tpb_nowait,
isc_tpb_protected,
isc_tpb_lock_read,
"EMPLOYEE"
例如2:
isc_tpb_version3,
isc_tpb_write,
isc_tpb_concurrency,
isc_tpb_nowait,
isc_tpb_protected,
isc_tpb_lock_read, "COUNTRY",
isc_tpb_protected, isc_tpb_lock_write,
"EMPLOYEE"
缺省的TPB是:isc_tpb_version3,isc_tpb_write,isc_tpb_concurrency,isc_tpb_wait。
通過上面的說明,我們對InterBase的事務處理有了一定的理解。那么這對我們實際的應用系統(tǒng)有什么參考價值呢?在此我給出一點看法,正確與否僅供大家參考。
1A、在線事務處理應用系統(tǒng):這些系統(tǒng)的顯著特點是大量并發(fā)用戶與數(shù)據(jù)庫交互,用戶基本都要對數(shù)據(jù)庫進行頻繁的改寫。建議使用如下的TPB參數(shù):
isc_tpb_version3
isc_tpb_read_committed
isc_tpb_rec_version或isc_tpb_no_rec_version,盡量用前者
isc_tpb_nowait
2B、混合應用系統(tǒng):這些系統(tǒng)的特點是既允許用戶對數(shù)據(jù)庫交互,又需要進行報表或數(shù)據(jù)決策,但側(cè)重于報表和數(shù)據(jù)決策。建議使用的TPB參數(shù):
isc_tpb_version3
isc_tpb_concurrency
isc_tpb_nowait
3、報表數(shù)據(jù)決策應用系統(tǒng):該系統(tǒng)的主要目的是進行報表處理或數(shù)據(jù)決策支持。這里邊又可分為兩類:
3C一類是不允許任何事務對數(shù)據(jù)庫進行改寫(只讀),純粹的報表和數(shù)據(jù)決策,建議使用的TPB參數(shù):
isc_tpb_version3
isc_tpb_read
isc_tpb_consistency
3D另一類是只允許當前活動事務對數(shù)據(jù)庫改寫而不允許其他并發(fā)事務改寫(排他寫),建議使用的TPB參數(shù):
isc_tpb_version3
isc_tpb_consistency
最后然我們看一下IBX、DBExpress、DataSnap對InterBase的事務處理。在這里我之所以沒有討論BDE,是因為BDE對InterBase的事務支持并不是很好,目前不大被推薦作為訪問InterBase的技術(shù)。
1、IBX
IBX使用IBTransaction控件進行事務控制。大多數(shù)人已經(jīng)了解了如何設置IBTransaction的屬性來讓其工作,我不再贅述。但是在IBTransaction中如何設置TPB來讓它滿足我們系統(tǒng)的需要呢?這就需要IBTransaction控件的params屬性了,我們可以在這個屬性改變TPB參數(shù),以此來改變對事務的控制。默認情況下如果你讓IBTransaction控件的params屬性為空,則相當于isc_tpb_version3、
isc_tpb_concurrency、isc_tpb_wait,這可能并不是你想要的。鼠標右鍵點擊IBTransaction控件,就會出現(xiàn)一個事務編輯器,共有四個選項。各選項意義與我們前面介紹的對應如下:
snapshot:相當于2B。
Read
Committed:相當于1A。
Read-Only Table Stability:相當于3C。
Read-Write Table
Stability:相當于3D。
如果這些選項不符合你的需要,你就要點擊params屬性自己編輯了。
2、DBexpress
DBexpress
中使用TSQLConnection控制事務。啟動事務的語句是:
procedure StartTransaction(TransDesc:
TTransactionDesc);需要一個事務描述類型作為參數(shù)。事務描述類型如下:
type
TTransIsolationLevel =
(xilDIRTYREAD, xilREADCOMMITTED, xilREPEATABLEREAD,
xilCUSTOM);
TTransactionDesc = packed record
TransactionID :
LongWord;
GlobalID : LongWord;
IsolationLevel :
TTransIsolationLevel;
CustomIsolation :
LongWord;
end;
我們看一下其事務隔離級別:
xilDIRTYREAD:臟讀,允許當前事務看到其他事務所作的任何更改,即便這些更改還沒有被提交。
xilREADCOMMITTED:讀提交,即允許當前事務只看到其他事務已提交的更改。但是如果在事務結(jié)束前有額外的更改提交,將得到不一致的數(shù)據(jù)視圖。
xilREPEATABLEREAD:確保當前事務得到一致的數(shù)據(jù)視圖。因此它僅僅允許該事務看到在該事務啟動時已經(jīng)提交的更改。
xilCUSTOM
:表示當前事務使用數(shù)據(jù)庫特定的隔離級別,由CustomIsolation指定。遺憾的是xilCUSTOM選項目前沒有支持。
通過對比可見,DBExpress的事務隔離中,xilREADCOMMITTED相當于InterBase的isc_tpb_read_commited+isc_tpb_no_rec_version,xilREPEATABLEREAD相當于isc_tpb_consistency。當然,如果TSqlconnection能提供xilCUSTOM選項就更好了,這樣便于結(jié)合數(shù)據(jù)庫類型更好的調(diào)整事務處理的方式。
3、Datasnap
DataSnap處理事務的模式在李維先生的書中有很好的描述。我們關(guān)鍵是要記住一點,當需要對數(shù)據(jù)庫進行改寫即調(diào)用ApplyUpdats時,DataSnap會自動啟動事務為你工作,這也是默認的方式,可能很多人就直接使用這種默認方式。可是我要強調(diào)一點,在這種默認方式下,DataSnap總是在當使用Tclientdataset時才進行事務處理,如果沒有使用Tclientdataset,DataSnap就不會自動進行處理事務。因此,如果中間層中你的數(shù)據(jù)集通過datasetProvider輸出給Clientdataset,就不會有什么問題嗯,但是那些沒有通過datasetProvider輸出到Clientdataset的數(shù)據(jù)集,就不會在datasnap的事務處理控制下,即便該數(shù)據(jù)集僅僅是讀操作,也需要嵌套在事務中進行,這是Interbase必須要求的。所以我的看法是,不論何時,還是使用顯式事務控制好。我們可以在中間層中,對于對數(shù)據(jù)庫的每一個操作都顯式地調(diào)用事務處理語句,并及時結(jié)束事務。這個做法對兩層結(jié)構(gòu)也同樣適用。
如果你沒有使用顯式事務控制,對于在中間層中使用IBX,要進行一些特別的設置,如:如果數(shù)據(jù)集準備通過DatasetProvider輸出給Clientdataset,
要設置數(shù)據(jù)集關(guān)聯(lián)的TIBTranSaction的AutoStopAction為saCommit,那些不通過DatasetProvider輸出給Clientdataset的數(shù)據(jù)集,其關(guān)聯(lián)的TIBTranSaction的AutoStopAction要設置為saNone。此外,在中間層中使用IBX,還要把數(shù)據(jù)集的UniDirectional屬性設置為true,使之成為單向的,因為我們不需要中間層為我們緩存數(shù)據(jù),而是通過客戶端的Clientdataset緩存數(shù)據(jù)。
最后,我還想說明一點,有很多人詢問在Interbase中如果對一條記錄加鎖。首先我認為這些人很是受其它關(guān)系數(shù)據(jù)庫系統(tǒng)模式的影響,沒有真正理解InterBase的多代結(jié)構(gòu)的工作原理。實際上在InterBase的多代結(jié)構(gòu)中,沒有必要對一條記錄加鎖,這也是一種不正常的做法。因此,從其它關(guān)系數(shù)據(jù)庫轉(zhuǎn)來使用InterBase的程序員,要轉(zhuǎn)變這個觀念,把心思更好的用在理解把握InterBase的版本事務模式和多代結(jié)構(gòu)上。
就寫這些,不當之處批評指正!
InterBase的事務管理
我們知道,與其它關(guān)系數(shù)據(jù)庫系統(tǒng)不同,InterBase采用獨特的多代結(jié)構(gòu)和版本事務來提高其性能,因此,對InterBase來說,事務就顯得尤其重要。為保證其版本事務的工作,InterBase要求任何一個對數(shù)據(jù)庫的訪問都必須包含在一個事務中進行,也就是說,無論對數(shù)據(jù)庫進行讀select、插入insert、更改update還是刪除delete都要先啟動一個事務,然后進行操作,操作完畢,結(jié)束事務。你不可能在沒有事務的情況下對數(shù)據(jù)庫進行操作。有的關(guān)系數(shù)據(jù)庫系統(tǒng)可能在讀操作下并不啟動事務,只有在改寫情況下才啟動事務,然而InterBase卻不同,你對此必須有清醒地認識。
我們?nèi)粘>幊?#xff0c;通常使用已經(jīng)編寫好的控件,這些控件如IBX、DBExpress已經(jīng)包含了事務處理的代碼,但是在底層,歸根結(jié)底都是通過InterBase的API函數(shù)進行的。
在InterBas的API函數(shù)中,事務處理常用的API函數(shù)有:
1、isc_start_transaction():使用已經(jīng)定義的TPB(事務參數(shù)緩存)在一個或多個數(shù)據(jù)庫上啟動一個新的事務。
2、isc_commit_retaining():提交事務的更改,但并不結(jié)束事務的執(zhí)行,仍然保留事務的上下文,可以再使用。
3、isc_commit_transaction():提交事務的更改,并結(jié)束事務的執(zhí)行,釋放上下文。
4、isc_rollback_transaction():回退事務的更改,并結(jié)束事務的執(zhí)行,釋放上下文。
啟動一個事務分為三個步驟:創(chuàng)建并初始化事務句柄,可選擇的創(chuàng)建并配置事務參數(shù)緩存,最后調(diào)用isc_start_transaction()。處理事務的永恒不變的原則是:任何事務都要盡可能地及時結(jié)束,不要拖延。
這里我想強調(diào)一點,那就是InterBase的事務啟動方式。通常情況下,對程序員和用戶來說InterBase事務有兩種啟動方式,隱含啟動和顯式啟動。大多數(shù)情況下大多數(shù)的程序員采用的是隱含啟動,也就是你并沒有明確調(diào)用(直接或間接)事務處理函數(shù)來處理事務,此時則由InterBase自動為你做這些工作。然而采用顯示的事務處理應該說是一種好的、值得推薦的方法,這可以有效地配合InterBase的多代結(jié)構(gòu)工作。當然顯示事務啟動需要自行調(diào)用(直接或間接)事務處理的函數(shù),就得多寫幾行代碼。
有些人不理解,既然InterBase能在你不顯式處理事務的情況下自動幫你處理,那還要我自己處理事務干什么?答案是:機器永遠沒有人聰明!它有時不知道應該及時結(jié)束一個事務!尤其在我們使用像IBX、DBExpress這樣的控件的時候,它們對事務的自動處理并不是盡善盡美的。
下面我們來了解一下事務參數(shù)緩存TPB。TPB對事務的執(zhí)行有著至關(guān)重要的影響。甚至可以毫不夸張的說,搞懂了TPB,也就搞懂了InterBase事務處理。然而,我們經(jīng)常使用的IBX、DBExpress等組件在底層封裝了事務處理API函數(shù),讓很多人不能明顯地(至少可以說不能像了解其他屬性那樣)了解TPB的含義。
TPB參數(shù)可分為如下幾類:
1、事務版本號:isc_tpb_version3,InterBase引擎內(nèi)部使用,表明事務的版本號。必須是TPB的第一個參數(shù)。
2、訪問模式:指明事務可以對數(shù)據(jù)表進行的操作。有isc_tpb_read、isc_tpb_write兩個選項。
1)isc_tpb_write:允許對表進行讀寫(select,insert,update,delete)操作,為缺省的訪問模式。
2)isc_tpb_read:只允許對表進行讀(select)操作。
只能設定一種訪問模式,否則后者將覆蓋前者。如果不指定,則使用缺省值。
3、事務之間的隔離級別:表明并發(fā)的事務間相互隔離的程度,也可以說是相互不受影響的程度。注意這里強調(diào)的是并發(fā)的事務。如果不是并發(fā)事務,則相互之間不會存在沖突,也就不需要進行相互間的隔離。事務的隔離級別通常有三級,分別是:
·read
dirty臟讀
·read committed提交讀
·consistency一致性
read
dirty臟讀是最低的隔離級別,它允許一個事務訪問另一個并發(fā)事務所作的還沒有提交的更改。由于這個隔離級別可以讀到其他事務未提交的數(shù)據(jù)或者不完整的數(shù)據(jù),因此可能造成數(shù)據(jù)的不一致性,所以在關(guān)系型數(shù)據(jù)庫系統(tǒng)中通常不被推薦。雖然從理論上講InterBase的多代結(jié)構(gòu)可以支持該選項,但實際上InterBase并不接受臟讀,因此實際中不要使用這個選項。BDE支持read
dirty。
因此InterBase只有有下列四個隔離選項:
isc_tpb_read_committed,
isc_tpb_rec_version
isc_tpb_read_committed,
isc_tpb_no_rec_version
isc_tpb_concurrency
isc_tpb_consistency
實際是三個隔離級別,由低到高分別是:
isc_tpb_read_committed
isc_tpb_concurrency
isc_tpb_consistency
顯然,隔離級別越高,并發(fā)性能越低。
1)isc_tpb_read_commited:這是InterBase中支持的最低隔離級別。它只允許一個事務訪問其他并發(fā)事務已經(jīng)提交的更改,沒有提交的更改即臟數(shù)據(jù)則不允許讀取。該選項可以充分發(fā)揮InterBase的多代結(jié)構(gòu)優(yōu)勢,提供高吞吐、高并發(fā)的性能。該隔離級別必須和其他兩個選項isc_tpb_rec_version、isc_tpb_no_rec_version之一配合使用。它們提供了對已提交更改更精細的訪問控制。
·isc_tpb_read_commited,isc_tpb_no_rec_version是缺省的調(diào)優(yōu)選項,表示事務只能讀取數(shù)據(jù)行的最新版本,如果該數(shù)據(jù)行的某個更改處于掛起狀態(tài)即還沒有提交,則不能被讀取。也就是說如果數(shù)據(jù)行的所有版本已全部提交,則該選項可以訪問到已經(jīng)提交的最新版本,但如果數(shù)據(jù)行還有未提交的版本,則不允許訪問該數(shù)據(jù)行,就連已提交的版本也不能讀取。如果使用isc_tpb_wait選項,那么此時事務只能等待其他事務提交或者回退這些未提交的版本數(shù)據(jù);如果使用isc_tpb_nowait選項,那么此時事務不會等待而是立即返回一個沖突錯誤。
·
isc_tpb_read_commited,isc_tpb_rec_version則表示事務可以立即讀取已提交的數(shù)據(jù)行最新版本,盡管該數(shù)據(jù)行最近還有多個掛起的未提交版本。也就是說,不管數(shù)據(jù)行是否存在未提交的版本,該選項總是可以讀到已提交的最新版本。這種情況下可能會產(chǎn)生沖突,要小心使用。
isc_tpb_read_commited選項特別適合用于和用戶交互的在線事務處理系統(tǒng)。
2)isc_tpb_concurrency:這是比read
committed高一級的隔離,相當于Snapshot,在BDE中又叫作重復讀Repeatable Read。
它允許一個事務獲得該事務啟動時數(shù)據(jù)庫的一個快照,此后,它只能看到自身對數(shù)據(jù)庫的更改,而其他并發(fā)事務的任何更改它均無法看到(這意味著這種隔離級別并不限制其他并發(fā)事務對數(shù)據(jù)庫的改寫,只是這些改寫看不到罷了)。由于要保持事務啟動時數(shù)據(jù)庫的一個快照,所以事務啟動時數(shù)據(jù)庫中記錄的所有版本必須也保持不變,這就必須禁止垃圾收集的運行。可見這個選項很適合于報表應用程序,因為無論重復幾次讀取表中的數(shù)據(jù)它總能獲得相同的數(shù)值。和其他關(guān)系數(shù)據(jù)庫系統(tǒng)不同,這個選項既提供了良好的重復讀功能(較長的讀事務),又不影響其他用戶事務的并發(fā)在線操作(如更改),充分發(fā)揮了InterBase的多代結(jié)構(gòu)優(yōu)勢,提供高吞吐、高并發(fā)的性能。該選項不大被推薦用來和用戶進行交互,因為用戶往往需要的是實時的數(shù)據(jù)而不是好像“凍住”了的數(shù)據(jù)。此外使用該選項的事務一定要盡快結(jié)束,不能拖很長時間。
3)isc_tpb_consistency:這是最嚴格的隔離級別,相當于強制重復讀Forced
Repeatable
Read,這也是InterBase特有的隔離級別,其他關(guān)系數(shù)據(jù)庫系統(tǒng)和BDE并不支持這種級別。在這種隔離模式下,如果一個表正被一個事務訪問,則不允許其他任何事務再對其進行改寫,即相當于在表上加了一把寫鎖。該選項一定要小心使用,因為它會極大地降低并發(fā)性能,并且一旦使用則一定要在操作完成后盡快結(jié)束事務。
隔離級別也只能設定一種,否則后者將覆蓋前者。
不隔離級別的事務之間的交互如下表:
各種事務隔離級別的對比如下表:
API
level constants & IBO. Language level & tools. BDE level.
(Not
supported) (Not supported) Dirty Read
Read Committed Read Committed Read
Committed
Concurrency Snapshot Repeatable Read
Consistency Snapshot table
stability (Not
supported)
4、鎖沖突的解決方案:表明當一個事務在寫操作(更該、刪除)期間遇到訪問沖突時將如何處理。
isc_tpb_wait是缺省的方式,表示事務必須要等待,直到其他并發(fā)事務結(jié)束,鎖定的資源被釋放。一旦資源被釋放,事務就重新嘗試其操作。
isc_tpb_nowait則表示事務只是返回一個沖突錯誤而不等待資源釋放,故此時事務不會再作嘗試。
這兩種方式也只能指定其中一種,否則后者將覆蓋前者。
5、表的保留方式:通常,事務只有在真正從數(shù)據(jù)表中讀無數(shù)據(jù)或往表中寫入數(shù)據(jù)時才獲得特定的訪問權(quán)。表的保留選項則表明了對事務訪問的特定表的訪問模式和鎖的解決方式。當這個選項被使用的時候,那么當事務啟動時,這個表就被保留著某種特定的訪問權(quán)限,而不是在表實際被訪問時。該選項在多個并發(fā)事務共享數(shù)據(jù)庫訪問的環(huán)境中才有用,它有如下三個主要目的:
·防止通常情況下的死鎖和更該沖突。
·由于觸發(fā)器和約束可能影響表的鎖,因此該選項可以提供依賴鎖。盡管沒有必要提供一個明顯的依賴鎖,但它能確保由于間接的表沖突而不產(chǎn)生更該沖突。
·可以在事務中改變對一個或多個單獨的表的訪問級別。
有效的保留方式有:
1)isc_tpb_shared
,isc_tpb_lock_write:允許使用isc_tpb_write訪問模式+
isc_tpb_concurrency或+isc_tpb_read_commited隔離級別的任何事務進行更改,而使用上述隔離級別+isc_tpb_read的事務可以讀取數(shù)據(jù)。
2)isc_tpb_shared
,isc_tpb_lock_read:可以允許任何事務讀取數(shù)據(jù),也允許使用isc_tpb_write訪問模式的事務更改數(shù)據(jù)。這是最自由的保留模式。
3)isc_tpb_protected,isc_tpb_lock_write:阻止其他事務更改。使用isc_tpb_concurrency或isc_tpb_read_commited隔離級別的可以讀取數(shù)據(jù),同時也只有這些事務可以更改數(shù)據(jù)。
4)isc_tpb_protected,isc_tpb_lock_read:禁止所有的事務更改數(shù)據(jù),同時允許所有的事務讀取數(shù)據(jù)。
TPB的格式如下:
版本號
訪問模式
隔離級別
沖突解決
表保留選項
例如1:
isc_tpb_version3,
isc_tpb_write,
isc_tpb_concurrency,
isc_tpb_nowait,
isc_tpb_protected,
isc_tpb_lock_read,
"EMPLOYEE"
例如2:
isc_tpb_version3,
isc_tpb_write,
isc_tpb_concurrency,
isc_tpb_nowait,
isc_tpb_protected,
isc_tpb_lock_read, "COUNTRY",
isc_tpb_protected, isc_tpb_lock_write,
"EMPLOYEE"
缺省的TPB是:isc_tpb_version3,isc_tpb_write,isc_tpb_concurrency,isc_tpb_wait。
通過上面的說明,我們對InterBase的事務處理有了一定的理解。那么這對我們實際的應用系統(tǒng)有什么參考價值呢?在此我給出一點看法,正確與否僅供大家參考。
1A、在線事務處理應用系統(tǒng):這些系統(tǒng)的顯著特點是大量并發(fā)用戶與數(shù)據(jù)庫交互,用戶基本都要對數(shù)據(jù)庫進行頻繁的改寫。建議使用如下的TPB參數(shù):
isc_tpb_version3
isc_tpb_read_committed
isc_tpb_rec_version或isc_tpb_no_rec_version,盡量用前者
isc_tpb_nowait
2B、混合應用系統(tǒng):這些系統(tǒng)的特點是既允許用戶對數(shù)據(jù)庫交互,又需要進行報表或數(shù)據(jù)決策,但側(cè)重于報表和數(shù)據(jù)決策。建議使用的TPB參數(shù):
isc_tpb_version3
isc_tpb_concurrency
isc_tpb_nowait
3、報表數(shù)據(jù)決策應用系統(tǒng):該系統(tǒng)的主要目的是進行報表處理或數(shù)據(jù)決策支持。這里邊又可分為兩類:
3C一類是不允許任何事務對數(shù)據(jù)庫進行改寫(只讀),純粹的報表和數(shù)據(jù)決策,建議使用的TPB參數(shù):
isc_tpb_version3
isc_tpb_read
isc_tpb_consistency
3D另一類是只允許當前活動事務對數(shù)據(jù)庫改寫而不允許其他并發(fā)事務改寫(排他寫),建議使用的TPB參數(shù):
isc_tpb_version3
isc_tpb_consistency
最后然我們看一下IBX、DBExpress、DataSnap對InterBase的事務處理。在這里我之所以沒有討論BDE,是因為BDE對InterBase的事務支持并不是很好,目前不大被推薦作為訪問InterBase的技術(shù)。
1、IBX
IBX使用IBTransaction控件進行事務控制。大多數(shù)人已經(jīng)了解了如何設置IBTransaction的屬性來讓其工作,我不再贅述。但是在IBTransaction中如何設置TPB來讓它滿足我們系統(tǒng)的需要呢?這就需要IBTransaction控件的params屬性了,我們可以在這個屬性改變TPB參數(shù),以此來改變對事務的控制。默認情況下如果你讓IBTransaction控件的params屬性為空,則相當于isc_tpb_version3、
isc_tpb_concurrency、isc_tpb_wait,這可能并不是你想要的。鼠標右鍵點擊IBTransaction控件,就會出現(xiàn)一個事務編輯器,共有四個選項。各選項意義與我們前面介紹的對應如下:
snapshot:相當于2B。
Read
Committed:相當于1A。
Read-Only Table Stability:相當于3C。
Read-Write Table
Stability:相當于3D。
如果這些選項不符合你的需要,你就要點擊params屬性自己編輯了。
2、DBexpress
DBexpress
中使用TSQLConnection控制事務。啟動事務的語句是:
procedure StartTransaction(TransDesc:
TTransactionDesc);需要一個事務描述類型作為參數(shù)。事務描述類型如下:
type
TTransIsolationLevel =
(xilDIRTYREAD, xilREADCOMMITTED, xilREPEATABLEREAD,
xilCUSTOM);
TTransactionDesc = packed record
TransactionID :
LongWord;
GlobalID : LongWord;
IsolationLevel :
TTransIsolationLevel;
CustomIsolation :
LongWord;
end;
我們看一下其事務隔離級別:
xilDIRTYREAD:臟讀,允許當前事務看到其他事務所作的任何更改,即便這些更改還沒有被提交。
xilREADCOMMITTED:讀提交,即允許當前事務只看到其他事務已提交的更改。但是如果在事務結(jié)束前有額外的更改提交,將得到不一致的數(shù)據(jù)視圖。
xilREPEATABLEREAD:確保當前事務得到一致的數(shù)據(jù)視圖。因此它僅僅允許該事務看到在該事務啟動時已經(jīng)提交的更改。
xilCUSTOM
:表示當前事務使用數(shù)據(jù)庫特定的隔離級別,由CustomIsolation指定。遺憾的是xilCUSTOM選項目前沒有支持。
通過對比可見,DBExpress的事務隔離中,xilREADCOMMITTED相當于InterBase的isc_tpb_read_commited+isc_tpb_no_rec_version,xilREPEATABLEREAD相當于isc_tpb_consistency。當然,如果TSqlconnection能提供xilCUSTOM選項就更好了,這樣便于結(jié)合數(shù)據(jù)庫類型更好的調(diào)整事務處理的方式。
3、Datasnap
DataSnap處理事務的模式在李維先生的書中有很好的描述。我們關(guān)鍵是要記住一點,當需要對數(shù)據(jù)庫進行改寫即調(diào)用ApplyUpdats時,DataSnap會自動啟動事務為你工作,這也是默認的方式,可能很多人就直接使用這種默認方式。可是我要強調(diào)一點,在這種默認方式下,DataSnap總是在當使用Tclientdataset時才進行事務處理,如果沒有使用Tclientdataset,DataSnap就不會自動進行處理事務。因此,如果中間層中你的數(shù)據(jù)集通過datasetProvider輸出給Clientdataset,就不會有什么問題嗯,但是那些沒有通過datasetProvider輸出到Clientdataset的數(shù)據(jù)集,就不會在datasnap的事務處理控制下,即便該數(shù)據(jù)集僅僅是讀操作,也需要嵌套在事務中進行,這是Interbase必須要求的。所以我的看法是,不論何時,還是使用顯式事務控制好。我們可以在中間層中,對于對數(shù)據(jù)庫的每一個操作都顯式地調(diào)用事務處理語句,并及時結(jié)束事務。這個做法對兩層結(jié)構(gòu)也同樣適用。
如果你沒有使用顯式事務控制,對于在中間層中使用IBX,要進行一些特別的設置,如:如果數(shù)據(jù)集準備通過DatasetProvider輸出給Clientdataset,
要設置數(shù)據(jù)集關(guān)聯(lián)的TIBTranSaction的AutoStopAction為saCommit,那些不通過DatasetProvider輸出給Clientdataset的數(shù)據(jù)集,其關(guān)聯(lián)的TIBTranSaction的AutoStopAction要設置為saNone。此外,在中間層中使用IBX,還要把數(shù)據(jù)集的UniDirectional屬性設置為true,使之成為單向的,因為我們不需要中間層為我們緩存數(shù)據(jù),而是通過客戶端的Clientdataset緩存數(shù)據(jù)。
最后,我還想說明一點,有很多人詢問在Interbase中如果對一條記錄加鎖。首先我認為這些人很是受其它關(guān)系數(shù)據(jù)庫系統(tǒng)模式的影響,沒有真正理解InterBase的多代結(jié)構(gòu)的工作原理。實際上在InterBase的多代結(jié)構(gòu)中,沒有必要對一條記錄加鎖,這也是一種不正常的做法。因此,從其它關(guān)系數(shù)據(jù)庫轉(zhuǎn)來使用InterBase的程序員,要轉(zhuǎn)變這個觀念,把心思更好的用在理解把握InterBase的版本事務模式和多代結(jié)構(gòu)上。
就寫這些,不當之處批評指正!
轉(zhuǎn)載于:https://www.cnblogs.com/fyen/archive/2011/05/07/2039594.html
總結(jié)
以上是生活随笔為你收集整理的FB/IB多代事务结构详解--对FB事务最好的讲解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【C#】三维立体验证码 (3DCaptc
- 下一篇: (学)新版动态表单研发,阶段成果----