因為spring的事務(wù)是通過AOP實現(xiàn)的世曾,因此在service中加鎖,鎖在事務(wù)內(nèi)部開啟的谴咸,放鎖后轮听,事務(wù)可能還沒提交;
//偽代碼
method() {
beginTransaction();
try {
//你的鎖是被代理方法里加的
targetMethod.invoke();
commit();
} catch (e) {
rollback();
}
}
在高并發(fā)情況下岭佳,這個鎖其實是無效的血巍。
例如:
//偽代碼
begin transaction;
synchronized {
//檢查name是否存在
boolean exist = checkExist(name);
//如果那么已存在,返回
if (exist) return;
//如果name不存在珊随,插入數(shù)據(jù)庫
insert(name);
}
commit;
以上的代碼述寡,在高并發(fā)情況下,例如兩個線程A和B同時執(zhí)行:
A線程開啟事務(wù)叶洞,將要插入name="張三"鲫凶;
B線程開啟事務(wù),也要插入name="張三";
A線程獲取鎖衩辟,B線程阻塞等待鎖螟炫;
A線程檢查name="張三"不存在,執(zhí)行插入數(shù)據(jù)庫操作艺晴;
A線程釋放鎖昼钻,B線程拿到鎖;
此時B線程查詢"張三"也不存在(因為A還未提交事務(wù))财饥;
B線程也插入了一條"張三"换吧;
A提交事務(wù);
B提交事務(wù)钥星;
至此,會發(fā)現(xiàn)數(shù)據(jù)庫有兩個張三满着!