@Transactional和synchronized能連用嗎?能保持事務的一致性嗎?

最近開發中遇到幻讀現象,大致情況如下,在一秒中多次點擊請求一個保存接口,再保存的時候會判斷數據庫是否已經存在同名的數據,由於請求過於頻繁,或者併發過大,第一次請求的數據還沒來得及提交到數據庫中,第二次請求已經發過來,這時數據庫中還沒有把第一次的數據保存到數據庫中,導致數據庫中總是多插入一條一模一樣的,產生了幻讀現象。解決方案大致有兩種:
第一種:給這個保存方法加鎖 synchronized ,(如果是多線程訪問可能不能保證事務的一致性)
第二種:加上 @Transactional(rollbackFor = Exception.class ,isolation = Isolation.SERIALIZABLE)提高這個保存的數據庫的隔離級別(這種方案能保證事務的強一致性,就是併發量太小)
實際使用中發現:第二種方案,由於數據庫的隔離級別過高導致系統的併發量降低,調用保存接口拿不到數據庫的鎖,導致保存失敗,所以只能用第一種方案
,同時網上查詢得知:@Transactional和synchronized同時使用並不能保證事務一致性,(但是我自己實測中並沒有發現失效的情況)原因大致如下:

由於spring的aop,會在@Transactional修飾的方法之前開啓事務,之後再加鎖,當鎖住的代碼執行完成後,在提交事務,
因此synchronized代碼塊執行是在事務之內執行的,可以推斷在代碼塊執行完時,事務還未提交,其他線程進入synchronized代碼塊後,讀取的庫存數據不是最新的。

你知道@Transactional和synchronized同時使用並不能保證事務一致性嗎
@Transactional註解和synchronized關鍵字不能同時使用

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