Spring注解和同步鎖不能同步問題解決
這篇文章主要介紹了Spring注解和同步鎖不能同步問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
結論:如果在service層的方法上同時使用事務和同步鎖無法保證數(shù)據(jù)同步。
@Service
public class ServiceImpl{
private static Lock lock = new ReentrantLock(false);
@Transactional(rollbackFor = Exception.class)
public void update() {
try {
lock.lock();
... ...
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
上面這個例子無法保證數(shù)據(jù)的一致性,synchronized 同理。
原因:
根據(jù)spring的AOP的特性,會在update方法之前開啟事務,之后再加鎖,當鎖住的代碼執(zhí)行完成后,再提交事務。
由于lock代碼塊執(zhí)行是在事務之內(nèi)執(zhí)行的,在代碼塊執(zhí)行完時,事務還未提交,因此其它線程進入synchronized代碼塊后,讀取的數(shù)據(jù)庫數(shù)據(jù)不是最新的(臟讀)。
解決方案:
1.在還沒有開啟事務之前就加同步鎖,用加鎖的方法調(diào)用加事務的方法
@Service
public class ServiceImpl{
private static Lock lock = new ReentrantLock(false);
public void update1() {
try {
lock.lock();
update2();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
@Transactional(rollbackFor = Exception.class)
public void uodate2() {
... ...
}
}
2.把鎖放到上一層
@Controller
public class TestController{
@Autowired
private IServiceImpl serviceImpl;
private static Lock lock = new ReentrantLock(false);
public String test() {
try {
lock.lock();
serviceImpl.update();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
@Service
public class ServiceImpl{
@Transactional(rollbackFor = Exception.class)
public void update() {
... ...
}
}
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Spring?boot?CommandLineRunner啟動任務傳參實例詳解
在使用SpringBoot構建項目時,我們通常有一些預先數(shù)據(jù)的加載,下面這篇文章主要給大家介紹了關于Spring?boot?CommandLineRunner啟動任務傳參的相關資料,需要的朋友可以參考下2022-06-06
springboot項目打包鏡像方式以及區(qū)分環(huán)境打包的方法
本文主要介紹了springboot項目打包鏡像方式以及區(qū)分環(huán)境打包的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-03-03

