我很喜歡壹句話:“八小時內謀生,八小時外發展。”
* * *棉:女::電腦:
描述:進來先看看風景。我相信會有光明。
我想大家都知道數據庫事務酸的本質(原子性、壹致性、隔離性和持久性),這裏就不寫了:grin:
我們都知道,事務是用來保證數據庫的完整性的,是用來保證所有SQL語句批量執行或者不執行的。
但是如果壹個方法和其他方法嵌套在壹起呢?當前方法和關聯方法都有事務嗎,還是只有其中壹些有事務,應該使用誰的事務?
事務傳播行為:當壹個方法在壹個已經打開事務的方法上運行時,無論當前方法是使用原始事務還是打開新事務。
通過@Transaction註釋中的傳播設置事務傳播行為。在…之中
有七種事務傳播行為:
下面寫壹個小演示,讓理解更快。
註意:賬戶表中的余額字段設置為無符號(即不能為負)。
壹個項目就是壹個普通的Spring項目。
模擬的是買書的過程,賬戶余額不足,但是壹次買多本書的情況,壹起支付。
在其中,我們將測試事務傳播行為的差異,以查看數據的變化。
初始代碼:
映射器層代碼
測試1:默認事務傳播行為
我們在Void Checkout (IntuserID,List ISBN)和void purchase(int userId,int isbn)中加入了@Transactional。
目前賬戶100元,兩本書價格分別為60和50,因為我們的支付流程采用循環購買。妳認為我們會買壹個還是不買?
答案當然是不能買任何,因為@Transactional註釋,默認事務的傳播屬性是:REQUIRED,即業務方法需要在壹個事務中運行。如果該方法在運行時已經在壹個事務中,那麽加入該事務,否則為自己創建壹個新事務。所以void purchase(int userId,int isbn)實際上使用了與調用它的方法相同的事務。畫壹個簡單的圖:
測試2:測試-& gt;REQUIRES_NEW屬性
其他代碼沒變,只有@ transactional的東西(propagation = propagation。requirements _ new)已添加到購買評論中。
REQUIRES_NEW:不管有沒有事務,業務方法總是為自己發起壹個新的事務。如果該方法已經在事務中運行,原始事務將被掛起,並將創建壹個新事務。在方法執行完成之前,新事務不會完成,而原始事務將繼續執行。
妳覺得答案和上面壹樣嗎?:獰笑:
答案是不同的。在第壹個測試中,我們實際上使用了結賬時的交易,而不是購買時的交易,如圖所示。
測試2:其事務傳播屬性如下:
所以妳可以買本書。
還有很多,意思已經解釋過了,沒有全部考過。
假設有兩個事務A和B同時執行。
1)臟讀:壹個事務從另壹個事務讀取壹個未提交的更新。
2)不可重復讀取:在同壹個事務中,多次讀取相同的數據會返回不同的結果(針對更新操作)。
3)幻影讀取:壹個事務讀取另壹個事務提交的插入數據(用於的插入操作)。
數據庫事務的隔離:數據庫系統必須具有隔離和並發運行各種事務的能力,使它們不會相互影響,避免各種並發問題。
壹個事務與其他事務隔離的程度稱為隔離級別。數據庫規定了很多事務隔離級別,不同的隔離級別對應不同的幹擾級別。隔離級別越高,數據壹致性越好,但並發性越弱。
在代碼中,我們可以使用
該數據庫提供了四種隔離級別:
註意:模擬並發。
1)測試mysql的默認隔離級別:
測試代碼很簡單,但是因為我是手動模擬,所以要破點,調試啟動,
當第壹本書價格翻倍=書店制圖者。getBookPricebyISBN (ISBN)語句執行後,應該去mysql修改圖書價格,這樣才能看到結果。
這個時候,我們會繼續執行。看什麽是輸出。
最後的結果還是五五開。因為mysql默認的事務間隔級別是可重復的,這意味著它可以在同壹個事務中被重復讀取。
註意:由於這是對數據庫的直接修改,其操作行為不可取,此處僅作模擬。結果有時不壹定準確。