REPEATABLE-READ隔离级别 事务中无法读到其它事务提交了的最新数据
前言:
業(yè)務要求一個簡單的并發(fā)控制,使得一條數(shù)據(jù)只被確認一次,我的方案是 悲觀鎖,就是在事務中先對數(shù)據(jù)行加鎖(MySQL InnoDB 行鎖基于索引),判斷是否已經確認過,未確認的情況下確認,已確認則事務提交釋放鎖。代碼寫完,結果發(fā)現(xiàn)未生效,就開始了滿腦子問號的排查過程。
業(yè)務代碼結構如下:
//不要這么做 //一沒對異常進行處理 //二事務的范圍太大包含很多不需要在事務中的代碼@Transactionalpublic void dangerConfirm(ConfirmDangerRequest request) throws CommonException {String zhiXinBianHao = request.getZhiXinBianHao();//此處方法中包含一次查詢操作 查詢表 A數(shù)據(jù)CodeWxid codeWxid = hisDaoService.getCode(request.getConfirmUserId());if (codeWxid == null || codeWxid.getWxId() == null){throw new CommonException("工號或企業(yè)微信id有問題", ResultStatusCode.INVALID_CAPTCHA);}//在此行打斷點先阻塞//悲觀鎖 鎖表B中的一行數(shù)據(jù) mybatisString lock = someMapper.lock("AED5ADC3C67E4A89AB7161DA84DC1FC1");System.out.println(lock);//用JPA查同一條數(shù)據(jù) 偷懶 表BBaseInfo baseInfo = baseInfoRepository.findByZhiXinBianHao("AED5ADC3C67E4A89AB7161DA84DC1FC1");//用mybatis查詢同一行的某個字段 表BString te = someMapper.te("AED5ADC3C67E4A89AB7161DA84DC1FC1");情況描述:
在MySQL命令行直接開事務,鎖同一行,此時上文代碼斷點往下執(zhí)行會等待鎖的釋放,正常。在命令行事務中更新數(shù)據(jù)中的某個字段,后提交。此時,調試代碼獲取到鎖,向下執(zhí)行時 發(fā)現(xiàn)問題:最后兩行,均未查出命令行已經提交的字段的值,即 無法讀到其它事務已經提交的數(shù)據(jù)。這和我所掌握的知識不符。
分析:
數(shù)據(jù)庫MySQL的隔離級別時 RR,不會出現(xiàn)臟讀和不可重復讀。問題是現(xiàn)在其它事務提交的都讀不到,但是數(shù)據(jù)庫軟件是可以查到的。沒辦法了,排除法,把所有與事務無關的注釋掉,一執(zhí)行,好了。。。。。。可以正常查到其它事務已提交的數(shù)據(jù)。
那么,自然地就定位到 下面這行的問題
//此處方法中包含一次查詢操作 查詢表 A數(shù)據(jù) CodeWxid codeWxid = hisDaoService.getCode(request.getConfirmUserId());加上上面這行,又不行了。。。。。除了悲觀鎖那行外,后面又讀不到其它事務提交的數(shù)據(jù)了。。
發(fā)現(xiàn)了這個現(xiàn)象,下面就開始做實驗(隔離級別為 REPEATABLE-READ):
起兩個MySQL命令行客戶端A、B,兩邊都?set autocommit = 0;?start transaction;
實驗一:A更新一條數(shù)據(jù)行 id = 1,值更新為 99,此時A不提交,B是查不到新值99的。A提交,B直接查詢此條數(shù)據(jù),可以查到值99。注意,在此之前B從未執(zhí)行過查詢操作。
實驗一:A更新一條數(shù)據(jù)行 id = 1,值更新為 99,此時A不提交,B是查不到新值99的。A提交,B先任意執(zhí)行一條查詢,再查詢此條id=1的數(shù)據(jù),就不可以查到值99,查到的是之前的舊值。
這好像很符合 REPEATABLE-READ隔離級別的定義
使用?set @@session.tx_isolation='read-committed'; 將AB會話的隔離級別調整為?read-committed。發(fā)現(xiàn):B事務任何情況下都可以讀到A事務剛提交的最新數(shù)據(jù)。
總結:
MySQL默認的隔離級別為?REPEATABLE-READ,這個隔離級別使得 前后讀取同一條的值是相同的,不會受其它事務的影響,除非它自己改變的。
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的REPEATABLE-READ隔离级别 事务中无法读到其它事务提交了的最新数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第2章 关系模型
- 下一篇: Typora 镜像下载/主题下载