SqlAlchemy的缓存问题,导致写和读不一致的问题解决
Flask作为服务端框架,SQLAlchemy作为数据库ORM框架。
假如Mysql中存在一个trace的表,内容为交易记录。
当使用ORM模式往其中写入数据后,再读取数据,从程序上输出结果会出现所谓的写入数据未被读取出来。
但是:手动在终端窗口读数据库的内容是已经更新了的。
于是排查代码,逻辑上没问题~~~
后来发现了SqlAlchemy的缓存这玩意,于是着手解决问题。
-
先了解了SqlAlchemy的缓存
SQLAlchemy 带有对象缓存机制,在重复查询相同的对象时,直接先查询本地的缓存,而不需要从数据库加载数据。
在每个 model 对象的内部,SQLAlchemy 在对象的 dict 中维护对象的状态。它往 dict 中加入对象的状态 _sa_instance_state,通过这个值来跟踪对象。_sa_instance_state 是 sqlalchemy.orm.state.InstanceState 类型,里面保存这个对象的 session 、orm mapper 等等信息。
在一般的情况下,这种方法会非常高效。但如果在进行跨进程操作时,如果不加以特别的处理,对象缓存机制会导致一个进程无法取得另外一个进程的对象更新情况。
如果是session是处于同一个进程,进行了写和读的操作,那没问题。如果写是A进程,读是B进程。假如B进程先读了一次,A进程写了一次,B进程再读一次,B进程读到第二次的结果就可能是第一次的结果(缓存问题)。 -
解决方法。
粗暴的解决方案可以再每次读取的前或者后刷新缓存,语法:
session.refresh 或 session.expire