Spring事務(wù)的四大特性
① 原子性 atomicity
原子性是指事務(wù)是一個不可分割的工作單位,事務(wù)中的操作要么都發(fā)生,要么都不發(fā)生。
事務(wù)是一個原子操作, 由一系列動作組成。 組成一個事務(wù)的多個數(shù)據(jù)庫操作是一個不可分割的原子單元,只有所有的操作執(zhí)行成功,整個事務(wù)才提交。
事務(wù)中的任何一個數(shù)據(jù)庫操作失敗,已經(jīng)執(zhí)行的任何操作都必須被撤銷,讓數(shù)據(jù)庫返回初始狀態(tài)。
② 一致性 consistency
事務(wù)必須使數(shù)據(jù)庫從一個一致性狀態(tài)變換到另外一個一致性狀態(tài)。
一旦所有事務(wù)動作完成, 事務(wù)就被提交。數(shù)據(jù)和資源就處于一種滿足業(yè)務(wù)規(guī)則的一致性狀態(tài),即數(shù)據(jù)不會被破壞。
比如a+b=100,一個事務(wù)改變了a比如增加了a的值,那么必須同時改變b,保證在事務(wù)結(jié)束以后a+b=100依然成立,這就是一致性。
③ 隔離性 isolation
事務(wù)的隔離性是指一個事務(wù)的執(zhí)行不能被其他事務(wù)干擾,即一個事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對并發(fā)的其他事務(wù)是隔離的,并發(fā)執(zhí)行的各個事務(wù)之間不能互相干擾。
在并發(fā)數(shù)據(jù)操作時,不同的事務(wù)擁有各自的數(shù)據(jù)空間,它們的操作不會對對方產(chǎn)生干擾。準確地說,并非要求做到完全無干擾。
數(shù)據(jù)庫規(guī)定了多種事務(wù)隔離級別,不同的隔離級別對應不用的干擾程度。隔離級別越高,數(shù)據(jù)一致性越好,但并發(fā)行越弱。
比如對于A對B進行轉(zhuǎn)賬,A沒把這個交易完成的時候,B就不知道A要給他轉(zhuǎn)多少錢。
④ 持久性 durability
持久性是指一個事務(wù)一旦被提交,它對數(shù)據(jù)庫中數(shù)據(jù)的改變就是永久性的,接下來的其他操作和數(shù)據(jù)庫故障不應該對其有任何影響。
數(shù)據(jù)庫管理系統(tǒng)一般采用重執(zhí)行日志來保證原子性、一致性和持久性。
重執(zhí)行日志記錄了數(shù)據(jù)庫變化的每一個動作,數(shù)據(jù)庫在一個事務(wù)中執(zhí)行一部分操作后發(fā)生錯誤退出,數(shù)據(jù)庫即可根據(jù)重執(zhí)行日志撤銷已經(jīng)執(zhí)行的操作。對于已經(jīng)提交的事務(wù)即使數(shù)據(jù)庫崩潰,在重啟數(shù)據(jù)庫時也能根據(jù)日志對尚未持久化的數(shù)據(jù)進行相應的重執(zhí)行操作。
Spring事務(wù)的傳播機制
Spring事務(wù)的隔離機制
一個事務(wù)與其他事務(wù)隔離的程度稱為隔離級別。
數(shù)據(jù)庫系統(tǒng)必須具有隔離并發(fā)運行各個事務(wù)的能力, 使它們不會相互影響, 避免各種并發(fā)問題。
對于同時運行的多個事務(wù), 當這些事務(wù)訪問數(shù)據(jù)庫中相同的數(shù)據(jù)時, 如果沒有采取必要的隔離機制,
就會導致各種并發(fā)問題。
隔離級別 | 存在問題 |
---|---|
READ UNCOMMITTED | 臟讀、不可重復讀、幻讀 |
READ COMMITTED | 不可重復讀、幻讀 |
REPEATABLE READ | 幻讀 |
SERIALIZABLE | 無 |
① DEFAULT(讀提交)
這是一個PlatfromTransactionManager默認的隔離級別,使用數(shù)據(jù)庫默認的事務(wù)隔離級別。
另外四個與JDBC的隔離級別相對應。大部分數(shù)據(jù)庫的默認級別都是READ_COMMITTED(讀取已提交)。
② READ_UNCOMMITTED(讀取未提交)
這是事務(wù)最低的隔離級別,允許當前事務(wù)讀取未被其他事務(wù)提交的變更。
這種隔離級別會產(chǎn)生臟讀,不可重復讀和幻讀。
產(chǎn)生臟讀場景:A事務(wù)讀取一個字段,但是這個字段被另外一個事務(wù)更新卻未提交,
再次讀取該字段時如果另外一個事務(wù)回滾則出現(xiàn)了臟讀現(xiàn)象(讀到的數(shù)據(jù)與第一次,
數(shù)據(jù)庫中的數(shù)據(jù)都不同)。
產(chǎn)生不可重復讀場景:A事務(wù)讀取一個字段,但是這個字段被另外一個事務(wù)更新并提交,
再次讀取該字段值不一樣則出現(xiàn)了不可重復讀現(xiàn)象(同一個事務(wù)中,不能保證讀取的字段值相同)。
產(chǎn)生幻讀場景:A事務(wù)讀取一個字段集合,但是這個表被另外一個事務(wù)更新并提交(如插入了幾行),
再次讀取該表可能會多幾行則出現(xiàn)了幻讀現(xiàn)象。
③ READ_COMMITTED(讀取已提交)
保證一個事務(wù)修改的數(shù)據(jù)提交后才能被另外一個事務(wù)讀取,
另外一個事務(wù)不能讀取該事務(wù)未提交的數(shù)據(jù)??梢员苊馀K讀,但不可重復讀和幻讀的現(xiàn)象仍然可能出現(xiàn)。
不可重復讀
A事務(wù)讀取一個字段,但是這個字段被另外一個事務(wù)更新并提交,再次讀取該字段值不一樣則出現(xiàn)了不可重復讀現(xiàn)象(同一個事務(wù)中,不能保證讀取的字段值相同)。
舉例就是對于一個數(shù)A原來是50,然后提交修改成100,這個時候另一個事務(wù)在A提交修改之前,
讀取到了A是50,剛讀取完,A就被修改成100了,這個時候另一個事務(wù)再進行讀取發(fā)現(xiàn)A就突然變成100了
幻讀
讀取一個字段,但是這個表被另外一個事務(wù)更新并提交(如插入了幾行),再次讀取該表可能會多幾行則出現(xiàn)了幻讀現(xiàn)象。
④ REPEATABLE_READ(可重復讀)
確保事務(wù)可以多次從某行記錄的一個字段中讀取相同的值,在這個事務(wù)持續(xù)期間,禁止其他事務(wù)對這個字段進行更新。這種事務(wù)隔離級別可以防止臟讀,不可重復讀,但是可能出現(xiàn)幻讀。
它除了保證一個事務(wù)不能讀取另一個事務(wù)未提交的數(shù)據(jù)外,還保證了在一個事務(wù)過程,
讀取的數(shù)據(jù)不會發(fā)生變化(即使數(shù)據(jù)庫中的數(shù)據(jù)在該事務(wù)過程中發(fā)生了變化)。
⑤ SERIALIZABLE :(可串行化)
在并發(fā)情況下和串行化的讀取的結(jié)果是一致的,沒有什么不同。這是花費最高代價但是最可靠的事務(wù)隔離級別,事務(wù)被處理為順序執(zhí)行。除了防止臟讀,不可重復讀外,還避免了幻讀。但性能十分低下!
⑥ 什么是臟讀、不可重復讀和幻讀?
臟讀: 對于兩個事務(wù) T1, T2。T1 讀取了已經(jīng)被 T2 更新但還沒有被提交的字段。之后, 若 T2 回滾, T1讀取的內(nèi)容就是臨時且無效的,也就是臟數(shù)據(jù)。
不可重復讀:對于兩個事務(wù) T1, T2。 T1 讀取了一個字段, 然后 T2 更新了該字段。之后, T1再次讀取同一個字段, 值就不同了。
幻讀:事務(wù)T1讀取一條指定where條件的語句,返回結(jié)果集。此時事務(wù)T2插入一些新記錄,恰好滿足T1的where條件。然后T1使用相同的條件再次查詢,結(jié)果集中可以看到T2插入的記錄,這些多出來的新紀錄就是幻讀。
不可重復讀和幻讀的區(qū)別:
不可重復讀重點是在update,即事務(wù)前后對比特定數(shù)據(jù)內(nèi)容的修改。而幻讀是insert和delete,即事務(wù)前后數(shù)據(jù)結(jié)果集的對比。
Oracle數(shù)據(jù)庫支持READ COMMITTED(默認) 和 SERIALIZABLE這兩種事務(wù)隔離級別。所以O(shè)racle不會出現(xiàn)臟讀。
MySQL 支持 4 種事務(wù)隔離級別:READ_UNCOMMITTED(讀取未提交),READ_COMMITTED(讀取已提交),REPEATABLE_READ(可重復讀-默認)和SERIALIZABLE (可串行化)。文章來源:http://www.zghlxwxcb.cn/news/detail-806983.html
Oracle 默認使用的是READ_COMMITTED(讀已提交)。MySQL默認事務(wù)隔離級別為 REPEATABLE_READ(可重復讀)。文章來源地址http://www.zghlxwxcb.cn/news/detail-806983.html
到了這里,關(guān)于Spring事務(wù)的四大特性+事務(wù)的傳播機制+隔離機制的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!