在我們日常的開發中,經常會接觸到事務和鎖,
當同時用到這二者的時候,你知道裏面的坑嗎?
比如,某個
service
裏的下面這段虛擬碼有問題嗎?
範例程式碼:
@Transactional(rollbackFor = Exception. class)
public Boolean test() {
Stringlock = "id";
synchronized (lock.intern()) {
// 業務程式碼
}
// 剩余邏輯
returntrue;
}
很顯然是有問題,因為
MySQL
的預設隔離級別是可重復讀,
因此在該事務送出前其他事務並不能獲取到該事務對數據操作後的結果,
那麽在第一個事務的
synchronized
塊執行完之後且事務送出之前,
其他事務在執行
synchronized
塊中的程式碼時使用的仍然是老數據,
從這方面來說其實就相當於沒有鎖住,也就是鎖失效。
那麽怎麽改呢?範例程式碼如下:
public Boolean test() {
Stringlock = "id";
PostServicepostService = (PostService) AopContext.currentProxy();
synchronized (lock.intern()) {
return postService.innerTest();
}
returntrue;
}
@Transactional(rollbackFor = Exception. class)
public Boolean innerTest() {
// 業務邏輯
returntrue;
}
上面的程式碼中我們沒有直接呼叫
innerTest
方法而是透過
AopContext
獲取的物件呼叫,
你知道為什麽嗎?歡迎投票並在評論區討論。
完整程式碼片段來源於程式碼小抄,歡迎點選進入小程式閱讀!
線上存取:https://www.codecopy.cn/post/gzshnr
更多優質程式碼歡迎進入小程式檢視!
往期推薦