代碼review的時候看到同事把業(yè)務(wù)鎖(insertDelete實(shí)現(xiàn))和業(yè)務(wù)操作放在一個事務(wù)里第岖。
代碼結(jié)構(gòu)如下:
```
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
? ? ? ? ? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? ? ? ? ? protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
?? bizLockRepoImpl.insert(biz_id,id);//其中biz_id是主鍵
?? xxxxx;
?? xxxxx;
?? xxxxx;
?? ……………;
?? bizLockRepoImpl.delete(biz_id,id);//其中biz_id是主鍵
});
```
頓感十分奇怪梁剔,這樣根據(jù)『事務(wù)隔離性』的原則漱牵,豈不是等于沒有做并發(fā)控制么?于是其馏,立馬安裝了個mysql進(jìn)行驗(yàn)證骗奖。實(shí)驗(yàn)如下,注意時序性:
實(shí)驗(yàn)一:
????? 目的:
????? 證明声功,雖然第一個事務(wù)還沒提交烦却,但是如果其他事務(wù)里的sql涉及到和執(zhí)行中的事務(wù)有主鍵沖突或者update了相同行的時候,其他的事務(wù)也是不能正常提交的先巴。
步驟:
???? 1. 開啟一個mysql終端:
??? 2. 開啟另外一個mysql終端:
???? 輸出insert語句其爵,就掛住了。等待了一段時間之后(一直不要去commit第一個事務(wù))伸蚯,報錯如上摩渺。『等鎖超時』剂邮。
???? 結(jié)論:
雖然我們知道數(shù)據(jù)庫具有隔離性『定義:當(dāng)多個用戶并發(fā)訪問數(shù)據(jù)庫時摇幻,比如操作同一張表時,數(shù)據(jù)庫為每一個用戶開啟的事務(wù)挥萌,不能被其他事務(wù)的操作所干擾绰姻,多個并發(fā)事務(wù)之間要相互隔離∪鹧郏』龙宏。數(shù)據(jù)庫引擎在事務(wù)commit前,也是會進(jìn)行一些保護(hù)(因?yàn)閿?shù)據(jù)庫引擎是怎么實(shí)現(xiàn)的還沒有去研究伤疙,先把表象說明白)银酗。
實(shí)驗(yàn)二:
????? 目的,看看我們所理解的數(shù)據(jù)庫事務(wù)的『隔離性』.
???? 1. 客戶端一:
??? 在一個事務(wù)里insert了一條記錄徒像,在這個事務(wù)里select是可以看到的黍特。
??? 2. 客戶端二:
??? 3. 客戶端一:
??? 執(zhí)行commit work;
??? 4. 客戶端二:
??? 再進(jìn)行select。
??? 結(jié)論:我們看到锯蛀,在事務(wù)一提交前灭衷,如果我們在其他的客戶端(即其他事務(wù)里)查詢是看不到事務(wù)一里還沒有commit的數(shù)據(jù)的。即我們討論的事務(wù)隔離性旁涤。