事務已提交另外會話查詢不到的問題解析
作者:沃趣科技 葉秀慧
事務已提交另外會話查詢不到的問題解析
導讀:
今天遇到一個很有趣的問題:跑python程式碼程式,使用python程式開啟兩個session連線資料庫,在第二個session往t表插入一行記錄,並commit了;在第一個session去查t表,發現t表中查詢不到剛插入的這條記錄記錄。而拿相同的python程式碼程式,在另一套環境上,也開啟2個session,重複上面的操作,結果居然可以查到記錄。開發人員認為,我在session 2上資料都插入進去了,並且提交了,為什麼sessioin 1查詢不到?並且相同的程式碼,連的同一個mysql環境,怎麼兩次結果都不一樣?
環境:
A環境:MySQL5.7.13 +相同的python程式碼+ Fedora22作業系統
B環境:MySQL5.7.13 +相同的python程式碼+ RedHat7作業系統
現象描述:
環境A的情況下,下面的實驗是模擬python程式碼程式跑的過程,如需使用python程式碼測試,詳見附錄3。
結論:在環境A的情況下模擬,在session 1中無法搜到session2提交的變更。
在環境B的情況下,也去跑這個python指令碼,但是跑出來的結果如下:
結論:在環境B的情況下模擬,在session 1中可以搜到session2提交的變更。
問題分析:
隔離級別問題
看到這樣的情況,我們理所當然的猜測,應該是隔離級別不同導致的,環境A的隔離級別應該是REPEATABLE-READ,可重複讀,什麼是REPEATABLE-READ?就是當你開啟一個事務,讀一個資料,而後再次讀,再讀,再讀……只要這個事務沒結束,那麼讀取的資料就是一致的。 所以,環境A下面,session1事務開啟,反覆查,結果是一致的,這很正常。
而環境B的隔離級別應該是READ-COMMITTED,提交讀,什麼是提交讀?就是隻要事務提交了,那你就能讀到修改的資料。所以,在環境B的情況下,session1第二次讀取的時候,就能讀到提交的資料。
好了,現在去資料庫看下,是不是我們猜測的情況。
環境A:
環境B:
事實擺在眼前,結果出乎我們的意料。環境A和環境B都是REPEATABLE-READ,啊啊啊,那到底是為什麼呢?。
auto commit問題:
明明是一模一樣的python程式碼,一樣的實驗環境,一樣mysql版本,一樣的執行過程,查詢到的結果就是不一致的?
唯一的不同,這2套環境的作業系統不一樣,環境A是Fedora22,環境B是redhat7,驗證中偶然發現,redhat7環境的autocommit變數居然還是on的。
預設情況下,python連線MySQL預設是自動開啟新事務,也就是說autocommit=OFF的。
好,現在要引入一個MySQL引數,autocommit。
什麼是autocommit?
autocommit這個變數表示是否開啟自動提交事務模式。如果將這個值設定為1,那麼所有變更無需手工提交,每次提交SQL語句,事務就會自動提交,馬上生效。如果設定為0,那麼你必須使用commit來提交事務或者使用rollback來回滾事務,事務不會自動提交。
問題的原因最終確定:環境B是因為自動提交了事務,session1才在第二次搜尋的時候,查到了修改的資料。
詳細解釋一下環境A和環境B的現象:
環境A:
環境A是Fedora22,autocommit設定為0,表示已經關閉,隔離級別是REPEATABLE-READ。所以在session1中第二次搜尋t表的時候無法搜尋到新插入的資料,因為兩次搜尋都在一個事務裡面,實現了可重複讀。如果要搜到新提交的事務必須鍵入commit;才能搜尋到
l 環境B
我們現在來分析情況環境B,環境B是RedHat7,autocommit設定為1,表示事務自動提交開啟,隔離級別是REPEATABLE-READ。所以對session1來說第二次去搜尋已經相當於已經是第二個事務了,當然就能搜尋得到session2提交的資料。
總結
提問:
透過上述的總結,各位看官可以嘗試回答幾個關於隔離級別的問題,來驗證下對隔離級別和自動事務提交引數的理解。
還是針對這2個session
Q1.在auto_commit=on,隔離級別是REPEATABLE-READ,T3時刻,session1能否看到session2在T2時刻提交的資料?
Q2.在auto_commit=off,隔離級別是REPEATABLE-READ,T3時刻,session1能否看到session2在T2時刻提交的資料?
Q3.在auto_commit=on,隔離級別是READ-COMMITTED,T3時刻,session1能否看到session2在T2時刻提交的資料?
Q4.在auto_commit=off,隔離級別是READ-COMMITTED,T3時刻,session1能否看到session2在T2時刻提交的資料?
回答:
Q1.能。
在auto_commit=on,隔離級別是REPEATABLE-READ,session1能看到session2在T2時刻提交的資料。因為auto_commit=on的時候,每一個語句都是一個全新的事物,所以在T3的時候,session3作為一個新的事務是能查詢到,session2在T2時刻提交的資料。
Q2.不能。
在auto_commit=off,隔離級別是REPEATABLE-READ,session1不能看到session2在T2時刻提交的資料。因為auto_commit=off的時候,對session1來說,在T3時刻,因為沒有提交,所以事務還是t1時候的那個事務,所以無法查到session2在T2時刻提交的資料。
Q3.能
在auto_commit=on,隔離級別是READ-COMMITTED,session1能看到session2在T2時刻提交的資料。因為auto_commit=1的時候,每一個語句都是一個全新的事物,所以在T3的時候,session1作為一個新的事物是能查詢到,session2在T2時刻提交的資料。
Q3.能
在auto_commit=off,隔離級別是READ-COMMITTED,session1能看到session2在T2時刻提交的資料。因為auto_commit=off的時候,雖然在T3的時候,session1還是T1時刻的那個事務,但是,READ-COMMITTED的特性就是可以看到已提交的事務。
附錄1:測試環境描述
附錄2:表結構
附錄3:python程式碼
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29734436/viewspace-2134267/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 查詢某個會話正在執行的事務會話
- 巧用閃回查詢來分析事務延遲的問題
- SR 3-2788269521 提交後查詢不到
- [BUG反饋]form表達提交查詢問題ORM
- Oracle阻塞會話查詢Oracle會話
- 會話及物件查詢會話物件
- 一個事務插入,另外一個事務更新操作,是否會更新成功?
- [20211014]如何取消使用者的查詢在另外的會話.txt會話
- Oracle 查詢事務數Oracle
- 事務複製會話 (三)會話
- 事務複製會話 (二)會話
- 事務複製會話 (四)會話
- 事務複製會話 (五)會話
- Ibatis 中文條件查詢不到資料問題BAT
- mySQL多表查詢與事務MySql
- 檢查Oracle的鎖狀態並清除問題會話Oracle會話
- Oracle查詢當前會話的sidOracle會話
- Oracle 查詢當前會話標識Oracle會話
- 統計Oracle 查詢事務數的方法Oracle
- 請教一個在完整提交前臨時儲存的問題(事務)!!
- 探究MySQL的DML提交事務的意義和DQL是否有必要提交事務MySql
- JDBC中事務的問題JDBC
- web service 的事務問題Web
- 查詢oracle正在執行的SQL和事務OracleSQL
- Spring Series---事務中JDBC是否自動提交解析SpringJDBC
- 一文帶你深度解析MySQL 8.0事務提交原理MySql
- 一個使用JDBC按Date查詢查詢的問題JDBC
- 未提交事務造成的等待事件事件
- 檢視mysql沒提交的事務MySql
- Spring中的事務提交事件Spring事件
- MySQL事務兩段式提交MySql
- MySQL 事務提交過程MySql
- java 事務提交/回滾Java
- SQL Server 查出未提交事務(長事務)SQLSQLServer
- 分頁查詢的排序問題排序
- 模板中的名字查詢問題
- Hibernate的Criteria查詢問題。
- 批次查詢的翻頁問題