DB大量出現select @@session.tx_read_only

在一次撈取Top SQL中,發現DB大量執行select @@session.tx_read_only,幾乎每一條DML語句前,都會有這麼一個sql。可是應用層並無作特殊處理,那麼這個SQL語句有什麼做用?是誰執行了它?html

此sql的做用主要是判斷事務是否爲只讀事務。MySQL自身會對只讀事務作優化,這是MySQL5.6.5 版本之後纔出現的。http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_tx_read_onlyjava

定位到MySQL的驅動包mysql

ConnectionImpl.java :sql

能夠看到,在if條件中,對MySQL的版本作了判斷,同時也有  !getUseLocalSessionState()  這麼一個條件,對應JDBC參數useLocalSessionState,當這個值爲false時,會發出select @@session.tx_read_only; 這條sql。服務器

默認狀況下,咱們的鏈接串信息沒有包含useLocalSessionState參數的設置,這個值默認爲false。
這個值的做用是驅動程序是否使用autocommit,read_only和transaction isolation的內部值(jdbc端的本地值)。
若是設置爲false,則須要這個判斷這三個參數的場景,都須要發語句到遠端請求,好比更新語句前,
須要發語句select @@session.tx_read_only確認會話是否只讀。session

若是設置爲true,則只須要取本地值便可。這能夠解釋爲何有的實例 select @@session.tx_read_only語句不少。優化

通常狀況下,驅動能夠保證本地值與遠程服務器值保持一致。當應用調用setAutoCommit, setTransactionIsolation 和 setReadOnly這三個接口設置參數值時,會與遠程服務器同步。spa

具體而言,server

當useLocalSessionState爲true時,若值與本地值不一致,則發往遠程更新;
當useLocalSessionState爲false時,不管設置值與本地值是否一致,每次都發往遠程更新。這能夠解釋爲何有些實例set autocommit語句比較多。htm

可是,若用戶設置參數時不經過JDBC接口(好比setAutoCommit),而是執行語句'set autocommit=xxx'設置,那麼就會存在本地值與遠程不一致的狀況,進而可能致使修改參數useLocalSessionState後,業務邏輯發生變化。

相關設置的SQL語句:

     set  autocommit=0  /*設置會話自動提交模式*/                                  對應的JDBC接口:      setAutoCommit(false)

     set tx_isolation='read-committed' /*設置事務的隔離級別*/             對應的JDBC接口:setTransactionIsolation('read-committed') 

     set tx_read_only=0;  /*設置只讀事務*/                                                 對應的JDBC接口:setReadOnly(false)

設置useLocalSessionState默認值爲ture,可能致使業務邏輯含義發生變化。觸發的條件是,用戶經過SQL語句直接設置自動提交參數,隔離級別參數或只讀事務參數。

相關文章
相關標籤/搜索