大家好,我是練習java兩年半時間的南橘,從一名連java有幾種數據結構都不懂超級小白,到現在懂了一點點的進階小白,學到了不少的東西。知識越分享越值錢,我這段時間總結(包括從別的大佬那邊學習,引用)了一些平常學習和工作中的重點(自我認為),希望給大家帶來一些幫助
這篇文章源於周五一次生產問題,公司代碼緊急上線之后,突然出現信息無法更新的問題。在排查日志文件以后,驚奇的發現沒有任何錯誤日志,同時一個事務中的兩個update方法竟然只有一條執行成功。
大家都感覺比較驚奇,然后開始肉眼對代碼進行review,這次出問題的代碼比較特殊,在測試環境中無法做到復刻,所以也沒辦法重現問題,在review的過程中,最開始以為是@transcational注解的問題,但是發現數據庫insert的信息並沒有被回滾。
最終,因為項目中引入了Mybatis-Plus,大家逐漸定位到了@version這一個注解上。
在官方文檔中,version注解並沒有太多解釋,但是我們都知道樂觀鎖的原理。
-
1 在取出記錄時,獲取當前的數據version=1
-
2 代碼更新時,帶上這個 version 1
-
3 執行更新時,set version = version +1 where version = version
-
4 如果 version 不對,就更新失敗
包括樂觀鎖還有CAS其他的一些問題,我們可以在這篇文章里深入了解【進階之路】包羅萬象——JAVA中的鎖
我們可以在代碼中復現這個問題。
首先我們的類中是有@version這個注解的
我們能夠看出,因為version值的相同,導致更新失敗了
然后我們去掉Version之后,又可以正常更新。
那我們如何解決這個問題呢?如果在一個方法內有兩個相同的類需要更新,我們在保證值的正確的情況下,可以主動給它+1,這樣就能改變它的預期,解決樂觀鎖的問題。
當然,樂觀鎖是有預期值B的,主動+2是沒有用的~
@Version 用於注解實體字段,必須要有,數據庫中也應有對應的字段,不然的話這次不會對代碼有任何的影響。
這是一次簡單的生產問題,而且很快就解決了,不過網上並沒有這樣的實例,但是它讓我們能夠更好地理解每一行代碼的含義,並且重新復習了一下樂觀鎖。
這是這篇文章的思維導圖,因為用的是免費版的軟件,所以有不少水印,需要原版的可以問我要