日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

REPEATABLE-READ隔离级别 事务中无法读到其它事务提交了的最新数据

發布時間:2024/3/13 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 REPEATABLE-READ隔离级别 事务中无法读到其它事务提交了的最新数据 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:

業務要求一個簡單的并發控制,使得一條數據只被確認一次,我的方案是 悲觀鎖,就是在事務中先對數據行加鎖(MySQL InnoDB 行鎖基于索引),判斷是否已經確認過,未確認的情況下確認,已確認則事務提交釋放鎖。代碼寫完,結果發現未生效,就開始了滿腦子問號的排查過程。

業務代碼結構如下:

//不要這么做 //一沒對異常進行處理 //二事務的范圍太大包含很多不需要在事務中的代碼@Transactionalpublic void dangerConfirm(ConfirmDangerRequest request) throws CommonException {String zhiXinBianHao = request.getZhiXinBianHao();//此處方法中包含一次查詢操作 查詢表 A數據CodeWxid codeWxid = hisDaoService.getCode(request.getConfirmUserId());if (codeWxid == null || codeWxid.getWxId() == null){throw new CommonException("工號或企業微信id有問題", ResultStatusCode.INVALID_CAPTCHA);}//在此行打斷點先阻塞//悲觀鎖 鎖表B中的一行數據 mybatisString lock = someMapper.lock("AED5ADC3C67E4A89AB7161DA84DC1FC1");System.out.println(lock);//用JPA查同一條數據 偷懶 表BBaseInfo baseInfo = baseInfoRepository.findByZhiXinBianHao("AED5ADC3C67E4A89AB7161DA84DC1FC1");//用mybatis查詢同一行的某個字段 表BString te = someMapper.te("AED5ADC3C67E4A89AB7161DA84DC1FC1");

情況描述:

在MySQL命令行直接開事務,鎖同一行,此時上文代碼斷點往下執行會等待鎖的釋放,正常。在命令行事務中更新數據中的某個字段,后提交。此時,調試代碼獲取到鎖,向下執行時 發現問題:最后兩行,均未查出命令行已經提交的字段的值,即 無法讀到其它事務已經提交的數據。這和我所掌握的知識不符。

分析:

數據庫MySQL的隔離級別時 RR,不會出現臟讀和不可重復讀。問題是現在其它事務提交的都讀不到,但是數據庫軟件是可以查到的。沒辦法了,排除法,把所有與事務無關的注釋掉,一執行,好了。。。。。??梢哉2榈狡渌聞找烟峤坏臄祿?/strong>

那么,自然地就定位到 下面這行的問題

//此處方法中包含一次查詢操作 查詢表 A數據 CodeWxid codeWxid = hisDaoService.getCode(request.getConfirmUserId());

加上上面這行,又不行了。。。。。除了悲觀鎖那行外,后面又讀不到其它事務提交的數據了。。

發現了這個現象,下面就開始做實驗(隔離級別為 REPEATABLE-READ):

起兩個MySQL命令行客戶端A、B,兩邊都?set autocommit = 0;?start transaction;

實驗一:A更新一條數據行 id = 1,值更新為 99,此時A不提交,B是查不到新值99的。A提交,B直接查詢此條數據,可以查到值99。注意,在此之前B從未執行過查詢操作。

實驗一:A更新一條數據行 id = 1,值更新為 99,此時A不提交,B是查不到新值99的。A提交,B先任意執行一條查詢,再查詢此條id=1的數據,就不可以查到值99,查到的是之前的舊值。

這好像很符合 REPEATABLE-READ隔離級別的定義

使用?set @@session.tx_isolation='read-committed'; 將AB會話的隔離級別調整為?read-committed。發現:B事務任何情況下都可以讀到A事務剛提交的最新數據。

總結:

MySQL默認的隔離級別為?REPEATABLE-READ,這個隔離級別使得 前后讀取同一條的值是相同的,不會受其它事務的影響,除非它自己改變的。

?

?

?

?

?

?

總結

以上是生活随笔為你收集整理的REPEATABLE-READ隔离级别 事务中无法读到其它事务提交了的最新数据的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。