在Oracle數據庫中,提供了一種被稱為“事務”的控制機制。通過事物,能夠完成對數據有效安全的修改操作,使數據庫中的數據達到一個數據一致的狀態。舉個簡單的例子,現在有一個借書系統中設涉及到兩張表,一張是圖書庫存表,一張是用戶借書情況表。在用戶借書的時候,數據庫需要進行兩個操作,一是從圖書庫存表中扣掉庫存;另一個操作時在用戶借書表中加入這個借書操作。數據庫在操作時,往往是先扣減庫存,然后再在用戶借書情況表中加入借書紀錄。假設用戶在借書的時候,第一步操作成功,即已經從圖書庫存表中扣除了某書的庫存;但是,在第二步時由于發現用戶借的書已經超量或者發現用戶的卡中還有罰款不能夠借書時,借書就會不成功。若沒有事務做控制的話,很明顯圖書庫存就會不準。而在事務的管理下,當第二步不成功的話,第一步操作就會發生回滾。也就是說,事務可以把數據庫的好幾個操作步驟當作一個整體,當其中有某個操作沒有成功的話,則所有操作都會發生回滾。Oracle數據庫就是通過這種機制來保障數據的一致性問題。
但是,事務若編寫的不好的話,則不但起不到應有的作用,還會大大降低數據庫的性能。如在數據庫事務執行時間比較長,就很有可能導致鎖沖突,從而降低數據庫的并發訪問性能。所以,數據庫管理員在編寫事務時,還是需要遵守幾個指導方針。
指導方針一:在事務中盡量使得訪問的紀錄最小。
在事務中,若執行Update等記錄操作語句,數據庫為了保障數據的一致性,會對其所訪問的記錄加鎖,防止在同一時間內其他用戶對其修改。此時,若其他用戶需要訪問加鎖的記錄,則必須等待。此時就會發生鎖沖突。
所以,在事務中要盡量使得訪問的記錄量最小。如此就可以減少鎖定的行數,從而減少事務之間的沖突。這要求數據庫管理員在事務中盡量精確的定位語紀錄。如在數據庫中讀取記錄時,最好能夠使用Where語句進行定位。并且在編寫Where語句的時候,要盡量的詳細,最好能夠實現一對一,則是最好的。
如在庫存盤點的時候,事務處理語句需要從數據庫中讀取一定數量的記錄,并且為這些記錄進行加鎖。此時,若記錄讀取的過多的話,就會對其他用戶訪問表中的記錄造成麻煩。為此,數據庫管理員應該建議應用前臺應用程序在開發的過程中,加入一些限制條件。如按照產品的分類來更新庫存。如此的話,就可以減少一個事務一次性讀取的記錄數量,從而把鎖的影響降低到最低。
指導方針二:保持事務盡可能的簡潔。
在事務中盡量使得訪問的紀錄最小,這是從數量的角度來考慮鎖沖突。而保持事務盡可能的簡潔,則是從時間的角度來考慮避免鎖沖突的事情。保持事務盡可能的簡潔,主要是要求數據庫管理員在編寫事務的時候,不要把事務寫的太過于龐大與復雜。否則,事務在執行的時候就會占用比較多的時間。而這直接導致的后果就是數據庫會把某些記錄、甚至一張數據表鎖住比較長的時間。這就會惡化鎖對數據庫的負面影響。
故當用戶在知道了必須要進行修改的記錄之后,就要馬上啟動事務;并且在最短時間內執行完相關的修改語句,然后立即遞交或者回滾。而且,只有在確實需要時,才打開事務語句。具體的來說,數據庫管理員在事務的簡潔性方面,可以嘗試如下方法。
一是在同一個事務中不要加入過多的修改或者刪除語句。如當用戶需要更新用戶信息表中的相關數據。例如在員工的編號前加入YG前綴并且同時根據員工入職年份計算員工工齡。
原文轉自:http://www.anti-gravitydesign.com