Spring中事物傳播機制爲七中類型。如圖:mysql
事物的ACID特性:spring
原子性(Atomicity):事務做爲一個總體被執行,包含在其中的對數據庫的操做要麼所有被執行,要麼都不執行。sql
一致性(Consistency):事務應確保數據庫的狀態從一個一致狀態轉變爲另外一個一致狀態。一致狀態的含義是數據庫中的數據應知足完整性約束。數據庫
隔離性(Isolation):多個事務併發執行時,一個事務的執行不該影響其餘事務的執行。編程
持久性(Durability):已被提交的事務對數據庫的修改應該永久保存在數據庫中。併發
spring實現事物開發的主要方式 聲明式事務編程和xml式事物編程開發。高併發
事物的隔離級別:性能
事務隔離級別,就是爲了解決上面幾種問題而誕生的。爲何要有事務隔離級別,由於事務隔離級別越高,在併發下會產生的問題就越少,但同時付出的性能消耗也將越大,所以不少時候必須在併發性和性能之間作一個權衡。因此設立了幾種事務隔離級別,以便讓不一樣的項目能夠根據本身項目的併發狀況選擇合適的事務隔離級別,對於在事務隔離級別以外會產生的併發問題,在代碼中作補償。spa
事務隔離級別有4種,可是像Spring會提供給用戶5種,來看一下:xml
一、DEFAULT
默認隔離級別,每種數據庫支持的事務隔離級別不同,若是Spring配置事務時將isolation設置爲這個值的話,那麼將使用底層數據庫的默認事務隔離級別。順便說一句,若是使用的MySQL,可使用"select @@tx_isolation"來查看默認的事務隔離級別
二、READ_UNCOMMITTED
讀未提交,即可以讀取到沒有被提交的數據,因此很明顯這個級別的隔離機制沒法解決髒讀、不可重複讀、幻讀中的任何一種,所以不多使用
三、READ_COMMITED
讀已提交,即可以讀到那些已經提交的數據,天然可以防止髒讀,可是沒法限制不可重複讀和幻讀
四、REPEATABLE_READ
重複讀取,即在數據讀出來以後加鎖,相似"select * from XXXfor update",明確數據讀取出來就是爲了更新用的,因此要加一把鎖,防止別人修改它。REPEATABLE_READ的意思也相似,讀取了一條數據,這個事務不結束,別的事務就不能夠改這條記錄,這樣就解決了髒讀、不可重複讀的問題,可是幻讀的問題仍是沒法解決
五、SERLALIZABLE
串行化,最高的事務隔離級別,無論多少事務,挨個運行完一個事務的全部子事務以後才能夠執行另一個事務裏面的全部子事務,這樣就解決了髒讀、不可重複讀和幻讀的問題了
併發下事務會產生的問題
舉個例子,事務A和事務B操縱的是同一個資源,事務A有若干個子事務,事務B也有若干個子事務,事務A和事務B在高併發的狀況下,會出現各類各樣的問題。"各類各樣的問題",總結一下主要就是五種:第一類丟失更新、第二類丟失更新、髒讀、不可重複讀、幻讀。五種之中,第一類丟失更新、第二類丟失更新不重要,不講了,講一下髒讀、不可重複讀和幻讀。
一、髒讀
所謂髒讀,就是指事務A讀到了事務B尚未提交的數據,好比銀行取錢,事務A開啓事務,此時切換到事務B,事務B開啓事務-->取走100元,此時切換回事務A,事務A讀取的確定是數據庫裏面的原始數據,由於事務B取走了100塊錢,並無提交,數據庫裏面的帳務餘額確定仍是原始餘額,這就是髒讀。
二、不可重複讀
所謂不可重複讀,就是指在一個事務裏面讀取了兩次某個數據,讀出來的數據不一致。仍是以銀行取錢爲例,事務A開啓事務-->查出銀行卡餘額爲1000元,此時切換到事務B事務B開啓事務-->事務B取走100元-->提交,數據庫裏面餘額變爲900元,此時切換回事務A,事務A再查一次查出帳戶餘額爲900元,這樣對事務A而言,在同一個事務內兩次讀取帳戶餘額數據不一致,這就是不可重複讀。
三、幻讀
所謂幻讀,就是指在一個事務裏面的操做中發現了未被操做的數據。好比學生信息,事務A開啓事務-->修改全部學生當天簽到情況爲false,此時切換到事務B,事務B開啓事務-->事務B插入了一條學生數據,此時切換回事務A,事務A提交的時候發現了一條本身沒有修改過的數據,這就是幻讀,就好像發生了幻覺同樣。幻讀出現的前提是併發的事務中有事務發生了插入、刪除操做。
不一樣隔離級別歲解決的事物問題:
mysql數據庫默認事物級別:
mysql默認的事務隔離級別爲repeatable-read
Oracle 默認:讀已提交
到此,spring中事物傳播機制和mysql數據庫默認事物隔離級別已經表述完畢,注意MyISAM是默認存儲引擎(Mysql5.1前)是不支持事物的。