現在的很多ORM架構對于事務的支援都是比較完善的,因為在很多的業務系統中事務是不可或缺的操作,通過事務操作開發者可以很容易保證資料的一緻性,接下來我們就來看看關于資料庫事務管理相關的内容。
什麼是事務?
在Java應用程式中對事務的定義可以了解為一種保證單一資料源操作情況下的資料一緻性機制,如下圖所示,可以抽象了解為對于一組連續的資料庫讀寫操作的控制,這些操作要不全部都成功,要不就是全部都不成功,不會出現部分成功部分失敗的情況。例如你去書店買了一本書,你隻能買一本書,而不能先買前200頁,後買後300頁。
在對關系型資料庫操作的時候,所有的SQL語句都必須在一個事務的執行範圍中進行控制,如果在操作的時候沒有對事務的邊界進行定義,那麼資料庫就會對每次的操作自動添加一個事務。事務操作開始于SQL操作執行之前,結束于SQL執行完畢之後,對于每個資料庫事務來講,可以被送出也可以進行復原。
事務操作的四大特征
Atomicity,原子性
事務的原子性是指将多個操作看做一組操作執行,那麼隻有目前組的所有資訊執行成功之後,整個事務才會執行成功。如果在執行過程中,目前執行組内任意一個操作執行失敗,那麼其他操作也将全部復原,整個事務操作也會執行失敗。
Consistency,一緻性
事務的一緻性是指,在每一次送出事務的過程中,資料庫的所有限制都要被強制遵守,并且不可違背,包括主鍵限制、資料類型等等。
Isolation,隔離性
事務隔離性是指,如果在某次操作過程中并發執行了多個事務,其最後所展示的結果與調用事務執行的順序是相同的,也就是說并行事務之間資料是可見的,但是操作是隔離的。
Durability,持久性
事務持久性是指,對每個操作成功的事務來講,對于資料的修改是永久改變的的,并且這些改變都會被記錄到一個持久化日志中,如果系統發生了當機,就可以根據這些持久化日志進行資料恢複操作。
事務隔離級别
根據上面的描述我們知道事務具有隔離性的特征,以此特征來保證資料在并發事務的時候的資料一緻性。根據規範我們将事務的并發控制劃分了不同的級别,稱之為事務隔離級别。标準的事務隔離級别有如下幾種。
- READ_UNCOMMITED
- READ_COMMITED
- REPEATABLE_READ
- SERIALIZABLE
在介紹事務隔離級别之前,首先我們先來了解一下關于資料一緻性的三個相關定義
髒讀
如圖所示,就是目前事務在執行資料操作的時候還沒有進行最後的Commit操作,這個時候就會有其他事務來對相關資料進行并發通路。但是由于後續的操作中出現了問題,導緻事務復原了,那麼這個時候已經讀取到的資料就成了髒資料。進而産生了資料髒讀的現象。
不可重複讀
如圖所示,如果兩個事務對同一條資料進行讀取,這個時候其中一個事務對資料進行了修改操作,這個時候當另一個事務讀取該資料的時候就不是自己想要的資料了,這個時候如果執行了相關的操作就會導緻資料不一緻的情況出現,是以在實際操作中我們通過讀鎖的方式來控制并發讀,防止這種問題出現。
幻讀
如圖所示,當一個事務正在從資料庫中讀取一批資料,在沒有讀取完成之前,有一個新的事務又往資料庫中新添加了一批資料,而且這些新的資料是滿足Transactions1的讀取條件,這個時候,由于第一次的事務讀取不會包含第二次事務送出的資料,這種情況我們就将其稱為是幻讀。
說完上面的三個概念,這個時候我們來看不同的事務隔離級别對于并發控制範圍的支援。如下圖所示
當然了,不同的資料庫也有自己對應的不同的資料庫預設隔離級别,如下圖所示
總結
在實際開發過程中,為了保證資料的一緻性,我們要根據實際情況對資料庫的隔離級别做出調整。實際上在大多數系統中,資料庫的處理能力與系統本身對于并發的支援都會影響到資料庫隔離級别的設定。
在設計系統的時候如果業務場景有高并發的特征,那麼就要犧牲一部分的資料一緻性,這樣隔離級别就會相對降低,而如果在有些系統中對于資料的一緻性要求較高的情況下,那麼資料庫的隔離級别就要相對調高一些,這樣做系統的處理能力會下降,但是,資料的一緻性會提高。