MySQL与幻象读
最近在部署系统的过程中,发现MySQL的一点问题,进行简单总结。
实际上就是关于事务隔离级别以及幻象读的问题。
我们的程序分成两个部分:UI层以及Service处理层。UI层使用MySQL的C库接口创建连接;Service层采用Python的MySQLdb您(底层仍然是MySQL的C接口)创建连接。
因此,实际上会与MySQL创建两个连接。
在windows环境中,如果我们通过UI修改了MySQL的数据,我们发现在service层查询时,还是以前的数据,而不是commit之后的数据。
采用Ubuntu系统下的MySQL时,没有这个问题。UI修改了MySQL数据后,Service能立刻查询到最新的结果。
我们发现,Ubuntu下的MySQL(5.1.49-1ubuntu8.1 (Ubuntu))版本较旧,采用MyISAM引擎。而Windows环境下的MySQL(5.1.53-community MySQL Community Server (GPL))较新,采用InnoDB引擎。将Windows环境下的MySQL强制指定为MyISAM时,问题也能解决,不再出现幻象读。
使用下述命令查询了Ubuntu和Windows的配置,都是REPEATABLE-READ:
SELECT @@tx_isolation;
SELECT @@global.tx_isolation;
判断,InnoDB的事务处理级别REPEATABLE-READ还是会出现幻象读。在程序中强行将session级的处理修改为READ-COMMITTED后,问题也解决,不再出现幻象读。
set session transaction isolation level read committed;
这个似乎与网上的资料有些不一致,据说REPEATABLE-READ不会出现幻象读,而READ-COMMITTED级别才会出现。实际结果是相反的。
另外,就我们的应用来说,select操作多于insert/update操作,而且数据量不大,因此MyISAM比InnoDB更适合我们的应用,可惜高版本的MySQL将缺省引擎给换成InnoDB了。