MySQL使用长连接时连接Innodb数据库时遇到的怪问题
因为在MySQL中存放的相关交易的数据都是用事务型的Innodb数据库。加上最近改造程序整体架构,把所有的MySQL的读取连接都改为了使用DButils的长连接,于是这就出现了一个诡异的问题:
明明交易的数据库中已经成功的提交了,但是在之前那个长连接中的查询出来的数据却没有任何变化。
这诡异的数据回溯问题在之前每次都新建立连接的情况下是没有的,只有长连接的情况下会出现这种问题。而且数据是确实的提交了的,并且用GUI工具查询的时候能够得到正确的结果。
先开始想到的办法是每次对Innodb数据库做查询操作的时候,首先使用COMMIT,或者ROLLBACK,这样确实可以得到正确的结果,但是每次都这么做未免也太奇怪了。
查阅了MySQL的手册,手册中是这么说的:
InnoDB默认是可重复读的(REPEATABLE READ)
而这个REPEATABLE READ的是最高级别的隔离,也就是不可读取未提交的任何数据。数据库会维持一个快照来实现这个功能。
虽然不知道具体是为什么,但是似乎之前DButils一直读取到的都是之前连入进去时候建立的快照信息。
于是简单的解决办法就是在建立长连接的时候执行:
“set session transaction isolation level read committed”
亦即将当前的会话的隔离级别设置为READ COMMITTED即可
或者在每次执行SQL语句之前执行COMMIT
明明交易的数据库中已经成功的提交了,但是在之前那个长连接中的查询出来的数据却没有任何变化。
这诡异的数据回溯问题在之前每次都新建立连接的情况下是没有的,只有长连接的情况下会出现这种问题。而且数据是确实的提交了的,并且用GUI工具查询的时候能够得到正确的结果。
先开始想到的办法是每次对Innodb数据库做查询操作的时候,首先使用COMMIT,或者ROLLBACK,这样确实可以得到正确的结果,但是每次都这么做未免也太奇怪了。
查阅了MySQL的手册,手册中是这么说的:
InnoDB默认是可重复读的(REPEATABLE READ)
而这个REPEATABLE READ的是最高级别的隔离,也就是不可读取未提交的任何数据。数据库会维持一个快照来实现这个功能。
虽然不知道具体是为什么,但是似乎之前DButils一直读取到的都是之前连入进去时候建立的快照信息。
于是简单的解决办法就是在建立长连接的时候执行:
“set session transaction isolation level read committed”
亦即将当前的会话的隔离级别设置为READ COMMITTED即可
或者在每次执行SQL语句之前执行COMMIT
评论
发表评论