1、事務(wù)
事務(wù)是指作為單個邏輯工作單元執(zhí)行的一系列操作。 事務(wù)處理可以確保除非事務(wù)性單元內(nèi)的所有操作都成功完成,否則不會永久更新面向數(shù)據(jù)的資源。通過將一組相關(guān)操作組合為一個要么全部成功要么全部失敗的單元,可以簡化錯誤恢復(fù)并使應(yīng)用程序更加可靠。數(shù)據(jù)庫服務(wù)器保證在事務(wù)范圍內(nèi)執(zhí)行的操作完整且正確地提交至磁盤,否則數(shù)據(jù)庫會復(fù)原至事務(wù)啟動之前的狀態(tài)。一個邏輯工作單元要成為事務(wù),必須滿足所謂的ACID屬性。ACID的具體含義如下:
1)A(Atomicity):操作序列要么完整的執(zhí)行,否則什么都不做;
2)C(Consistency):一致性,事務(wù)執(zhí)行后,保證數(shù)據(jù)庫從一個一致性狀態(tài)到另外一個一致性狀態(tài);
3)I(Isolation):隔離,一個事務(wù)的中間狀態(tài)對其他事務(wù)不可見,即每個用戶都感覺他們在單獨(dú)使用數(shù)據(jù)庫。隔離級別用來定義多大程度的隔離多個不同的事務(wù);
4)D(Durability):持久性,事務(wù)的有效性,不會應(yīng)用硬件或軟件的失敗而丟失。
2、并發(fā)控制
1)相關(guān)概念
i)隔離(+一致性) => 并發(fā)控制;
ii)多個事務(wù)可以訪問或修改相同的資源;
iii)只要多個進(jìn)程共享資源,就需要對訪問進(jìn)程進(jìn)行排隊控制;
iv)在進(jìn)行并發(fā)控制時,數(shù)據(jù)庫內(nèi)部將生成多個并發(fā)事務(wù)訪問資源的操作序列表,并且每一個事務(wù)內(nèi)部的各個操作都需要序列化。
2)串行調(diào)度存在的問題
在串行調(diào)度中,采用操作序列,一個事務(wù)完成了再完成另外一個,即使兩個事務(wù)T1、T2更新的是數(shù)據(jù)庫中不同的對象。此種方式從并發(fā)和性能角度考慮,都不能很好的利用計算機(jī)資源。
為了改善性能,需要采用非串行調(diào)度,即允許事務(wù)并發(fā)執(zhí)行,即一個事務(wù)內(nèi)的操作可以在其他事務(wù)提交前開始執(zhí)行。
3)并發(fā)調(diào)度的常見問題
i)臟讀:事務(wù)T2讀取到了事務(wù)T1沒有提交的結(jié)果
例如如下的操作序列會導(dǎo)致臟讀:
事務(wù)T1讀取記錄,然后更新記錄;
事務(wù)T2讀取了更新后的記錄;
若T1后續(xù)操作失敗,會導(dǎo)致更新的記錄回滾,而同時事務(wù)T2已經(jīng)使用了這個沒有提交的值。
ii)不可重復(fù)讀:事務(wù)T1中多個讀操作返回不同的結(jié)果
事務(wù)T1讀取一個對象;
事務(wù)T2讀取并更新同一個對象;
事務(wù)T1再次讀取同一個對象返回了不同的值。
iii)幻影讀:如果事務(wù)T1在同樣的情況下多次執(zhí)行select讀取的結(jié)果不同
事務(wù)T1從一個表中檢索滿足特定條件的記錄返回m條記錄;
事務(wù)T2往該表中insert/delete其他滿足相同條件的記錄;
事務(wù)T1再次以相同的條件檢索該表的數(shù)據(jù)返回的數(shù)據(jù)記錄不為m條。
3、鎖機(jī)制
1)相關(guān)概念
i)用戶可以鎖定一個對象,可以防止 其它用戶修改鎖定的對象;
ii)在多個用戶并發(fā)訪問數(shù)據(jù)庫的情況下,為保證數(shù)據(jù)完整性,鎖是很有必要的;
iii)程序可以顯式的對數(shù)據(jù)枷鎖,數(shù)據(jù)庫系統(tǒng)可以隱式的對對象進(jìn)行加鎖。
2)鎖的類型
i)共享鎖(Shared locks):多個用戶可以讀取相同的記錄
如果一個對象上沒有排他鎖,則共享鎖可以加在該對象上,它可以防止其他事務(wù)更新數(shù)據(jù),但同時,其他事務(wù)可以讀取該數(shù)據(jù),多個事務(wù)可以在同一個對象上加多個共享鎖。
ii)排他鎖(Exclusive locks):同一時間僅僅有一個用戶可以讀取相同的記錄
如果一個對象上沒有任何鎖,排他鎖才可以加在該對象上。一旦在記錄上加了排他鎖,則不能在該記錄上增加任何鎖了,直至鎖釋放。它可以防止其他事務(wù)讀取和更新數(shù)據(jù)。
iii)提升/更新鎖(Promotable/Update lock):可以對鎖進(jìn)行升級或者降級
在更新游標(biāo)時使用,由游標(biāo)在含有“for update”選項執(zhí)行時產(chǎn)生,只能在沒有排他鎖或其他更新鎖的記錄上加更新鎖。當(dāng)鎖定的記錄真正執(zhí)行的時候,更新鎖將提升為排他鎖。
iv)專一鎖(Intent lock):是一種表級鎖,標(biāo)識在該表上有一個游標(biāo)在讀取數(shù)據(jù)
由IDS自動分配,如果一條記錄上的記錄被更新,一個排他鎖將分配在該記錄上,同時將該記錄的表上自動加上專一鎖,這能保證沒有session可以在該表上增加排他鎖,只要該表中有記錄被增加了排他鎖。
3)鎖的有效期
i)程序可以控制數(shù)據(jù)庫鎖的有效期;
ii)當(dāng)數(shù)據(jù)庫關(guān)閉后,數(shù)據(jù)庫鎖將被釋放;
iii)根據(jù)數(shù)據(jù)庫使用了事務(wù)的情況,表鎖的有效期不同。如果數(shù)據(jù)沒有使用事務(wù)(沒有使用事務(wù)日志,也不使用commit work語句),顯式對一個表lock,當(dāng)執(zhí)行unload table時,鎖將被釋放;
iv)當(dāng)數(shù)據(jù)庫使用了事務(wù),事務(wù)結(jié)束時,將釋放事務(wù)所有的鎖。
4)不同粒度的鎖
i)數(shù)據(jù)庫級別的鎖:數(shù)據(jù)庫管理活動,比如imports和exports。例如:

創(chuàng)建排他鎖實例:




iv)行級鎖:OLTP事務(wù)采用行級鎖效率高。創(chuàng)建表時指定為行級鎖的參考語句如下:



i)如果更新表中相對較小一部分?jǐn)?shù)據(jù)的時候,采用行級鎖將獲取最好的性能,如果一個事務(wù)只訪問表中的一小部分?jǐn)?shù)據(jù),那就采用行級鎖。
ii)如果一個事務(wù)頻繁訪問整個表中的數(shù)據(jù),設(shè)置更粗的力度,比如表級鎖;
iii)如果更新數(shù)據(jù)庫中大部分表的大部分?jǐn)?shù)據(jù)的情況下,采用數(shù)據(jù)庫級別的鎖;
iv)informix默認(rèn)的鎖模式為頁級鎖。
v)ONCONFIG參數(shù)DEF_TABLE_LOCKMODE用于設(shè)置默認(rèn)鎖模式;
vi)查看表鎖模式的方法如下:
方法1:


1)Dirty Read(臟讀)
設(shè)置為Dirty Read隔離級別的參考語句如下:

靜態(tài)表(沒有更新,只讀的表),速度比100%準(zhǔn)備更重要的情況,以及不能等待鎖的釋放的情況中。
2)Commited Read(只讀已提交的數(shù)據(jù))
設(shè)置為該級別的參考語句如下:

在讀取數(shù)據(jù)前,數(shù)據(jù)庫服務(wù)器嘗試在記錄上加共享鎖。加鎖前,需要先檢查是否可以對對象加共享鎖;如果可以加鎖,則要保證要加鎖的記錄沒有其他進(jìn)程正在更新;當(dāng)繼續(xù)正在更新時,記錄上有排他鎖,此時我們不能對記錄加共享鎖。
3)Cursor Stability(游標(biāo)穩(wěn)定性)
參考設(shè)置語句如下:

4)Repeatable Read(可重復(fù)讀)
參考設(shè)置語句如下:

數(shù)據(jù)庫在讀取的記錄上加共享鎖,驗證是否可以讀取數(shù)據(jù),直到事務(wù)提交,鎖才能釋放,其他用戶可以讀取數(shù)據(jù),但是不能修改。可以保證在同一事務(wù)中前后兩次讀取記錄是一致的。當(dāng)必須要信任所有讀取的記錄,保證記錄不被修改,我們可以采用repeatable read,例如統(tǒng)計數(shù)據(jù)(銀行賬號的余額情況)、關(guān)聯(lián)查詢多個表等。
5)Last Committed Read(讀取最后提交的數(shù)據(jù))
這是一種樂觀鎖,它解決了Commited Read的不足,因為Commited Read在記錄被鎖時,其它進(jìn)程需要等待。
這種隔離級別常被用在WEB應(yīng)用系統(tǒng)中,例如在電子商務(wù)系統(tǒng)中,可以選擇商品添加到購物籃中,但是此時后臺可能你正在對商品的價格進(jìn)行更新,當(dāng)再次檢查的時候,可能發(fā)現(xiàn)商品的價格已經(jīng)發(fā)生變化。
設(shè)置語句參考如下:

相對Committed Read而言,提高了并發(fā)量和系統(tǒng)的吞吐量。可以通過ONCONFIG參數(shù)設(shè)置為隔離級別:USELASTCOMMITTED。表需要設(shè)置為行級鎖,不能是頁級鎖。
6)幾種隔離級別的比較
隔離級別 臟讀? 不可重復(fù)讀? 幻影讀?
Dirty Read Yes Yes Yes
Last Commited Read No Yes Yes
Commited Read No Yes Yes
Cursor Stability No No Yes
Repeatable Read No No No
5、設(shè)置事務(wù)/會話的鎖模式
1)不等待鎖的釋放
為默認(rèn)的鎖模式,如果數(shù)據(jù)庫對象被鎖,則立即返回錯誤。錯誤消息參考如下:



一個事務(wù)可能發(fā)生死鎖或掛住,等待資源的釋放。設(shè)置為此種模式的語句如下:

直到等待n秒后,如果鎖一直沒有釋放將返回鎖等待超時錯誤信息。參考設(shè)置語句如下:

1)監(jiān)控session的隔離級別
使用: onstat –g sql 或者 onstat –g ses,例如在筆者測試服務(wù)器上運(yùn)行onstat -g sql,運(yùn)行結(jié)果如下:









































2)查看用戶進(jìn)程鎖等待情況
使用: onstat –u。
3)查看鎖使用和等待情況
使用: onstat -k
4)監(jiān)控數(shù)據(jù)庫事務(wù)及其狀態(tài)
使用: onstat -x