场景:
在flask框架中,起了一个线程,线程中会定时循环查询LogAlarm表的最新的内容并展示,数据的获取是通过ORM连接进行查询的,如下:
每5秒进行一次查询
logs = LogAlarm.query.filter(LogAlarm.level <= int(level), LogAlarm.action == 0).limit(100)
问题:
在LogAlarm表新增或删除或者修改了数据之后,每次获取的数据不变,还是第一次获取的数据。
解决方案:
在每次查询之后,加上事务提交:
logs = LogAlarm.query.filter(LogAlarm.level <= int(level), LogAlarm.action == 0).limit(100)
db.session.commit()
原因:
基于InnoDB默认的repeatable read事务隔离和select为快照读可知,连接池中的连接在初始化时,没有设置autocommit为True,会导致复用同一个连接的多次select查询其实都在一个事务内,且都为快照读,这样,每个select查的数据源并不是表中的最新数据,而是第1个查询时的快照,因此导致查不到表中其他事务写入的最新数据。
所以解决方法是
- 将autocommit设置为True后,每个事务中只有1个查询,下一个查询属于一个全新的事务,这样就能读到新事务开始前的最新数据了。
- 如果由于项目原因不能将autocommit设置为True,那么就需要在每次查询后,手动加上commit即可,那么下次的查询就会是一个新的事务。