问题
General log中出现大量SQL “SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ”。
该语句会引起两个问题,
1: "REPEATABLE READ"不是我们预期的事物隔离级别。
2: 大量无效的SQL影响性能。
注: MySql的可重复读会带来怎样的问题,可以参考该文章。https://www.jianshu.com/p/f7360d259878
排查
排查过程涉及到以下几个方面:
-
Druid Datasource框架创建连接池
-
Jdbc连接初始化过程
-
MySql 版本间SQL语句差异
-
MyCat工作原理
-
Spring框架如何管理事物
Druid Datasource框架创建连接池
Jdbc连接初始化过程
MySql 版本间SQL语句差异
由上图可以见,对于具体发送哪一条SQL语句去向MySql服务端请求事物隔离级别由版本决定的。MySql的版本5.7.20是一个分界线。
对于小于5.7.20的MySql版本使用的是“select @@session.tx_isolation”。
对于大于5.7.20的MySql版本使用的是“select @@session.transaction_isolation”
MyCat工作原理
mycat 在server.xml中设置隔离级别为RC,mysql级别设置隔离级别为RC。
但是,连接mycat,通过 “select @@session.tx_isolation” 查出来的隔离级别是RR。
通过 “select @@session.transaction_isolation” 查出来的隔离级别是RC。
如下两图所示,
连接MyCat的情况:
直接连接MySql的情况:
Spring框架如何管理事物
注: Spring事物原理分析,可以参考该文章。 https://www.jianshu.com/p/ecf55d6f0118
修复
- 使用本地事物级别代替向服务端发送请求询问隔离级别(“&useLocalSessionState=true”,驱动程序是否应引用autocommit的内部值,以及由Connection.setAutoCommit()和Connection.setTransactionIsolation()设置的事务隔离)
- MyCat使用参数 “5.7.20” 向客户端返回正确的版本信息。用来消除版本之间SQL的细微差别。