spring synchronized鎖和事務

最近發現有同事寫了一段事務控制的方法中子方法加了鎖的代碼,而且在事務上用了propagation = Propagation.REQUIRES_NEW,然後稍微研究了下,得出以下結論:

1. propagation = Propagation.REQUIRES_NEW在執行方法時,不管之前有沒有事務,都會創建新的事務,而且這個一般用於嵌套事務的內層事務中,像xxx那樣寫也有效,不過一般不那樣用。
2. 目前用的是事務(_NEW)在外層,鎖在內層的寫法,這種寫法有風險。併發情況下,A在執行有鎖的部分並且有自己的事務,B進來時會創建自己的事務(因爲用了_NEW)並且等A執行完有鎖的部分。等A執行完有鎖的部分,A事務開始執行save,B開始執行有鎖的部分,如果A save還沒提交,B還是會拿到舊的。 間隔時間很短的情況會取到舊數據,人工很難重現。
3. 如果繼續用這種寫法,但不用_NEW,用默認事務,會這樣子:在執行有鎖的部分並且有自己的事務,B進來時會用A的事務並且等A執行完有鎖的部分。等A執行完有鎖的部分,A事務開始執行save,B開始執行有鎖的部分,如果B save還沒提交,A save也不會提交,這樣B拿到的肯定是舊的。而且這樣很亂,肯定是錯的。
4. 建議寫法是鎖在外層,事務在內層,這樣事務就會被鎖管理,事務執行完後鎖纔會被釋放,原理是鎖管理事務。

5. 在service層如果用一個加鎖的外層函數調用有事務控制的方法,sonarQube(一個代碼風格檢查工具)提示可能會有問題,後面在controller那邊加了鎖,不過之後還是要看下在service層到底有什麼問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章