覆盖Django mysql model中save方法时碰到的一个数据库更新延迟问题

覆盖Django mysql model中save方法时碰到的一个数据库更新延迟问题,第1张

概述最近有一个需求,通过django的admin后台,可以人工配置5张表的数据,这些数据进行一些业务规则处理后会统一成一份数据缓存在一个cache之中供服务端业务访问,因而任何一张表的数据更新(增、删、改

最近有一个需求,通过django的admin后台,可以人工配置5张表的数据,这些数据进行一些业务规则处理后会统一成一份数据缓存在一个cache之中供服务端业务访问,因而任何一张表的数据更新(增、删、改),都要需要重新根据规则计算数据结果,并更新cache。

首先想到的方法就是覆盖每个表model子类中的save方法,在其中先调用父类的save方法走原有保存逻辑更新数据到数据库后,之后再单独调用一次cache的更新逻辑,这样每张表的任意数据被用户更新后,都将先触发model的数据库更新、而后执行cache的数据更新,其中Application表model的代码如下所示:

 1 class Application(models.Model): 2     name = models.CharFIEld(max_length=128,blank=False,verbose_name=u'应用名') 3     description = models.TextFIEld(blank=False,1)">应用描述 4     status = models.IntegerFIEld(verbose_name=u状态',choices=APPliCATION_STATUS) 5     mtime = models.DateTimeFIEld(blank=False,1)">修改日期True) 6     ctime = models.DateTimeFIEld(blank=False,1)">创建日期 7      Meta: 8         db_table = application' 9         verbose_name_plural = u应用10 11     def save(self,*args,**kargs):12         super(Application,self).save(*args,1)">kargs)13         # 更新memcached逻辑实现函数,该函数为通用函数一部分,会单独建立MysqL连接,查询数据库数据,并更新到memcached14         update_memcached_from_MysqL()

这样每次在web上新增或者修改数据表记录时,都会先执行父类save *** 作,save完成后,又会执行update_memcached_from_MysqL函数,从mySQL查询到最新数据,而后更新到cache之中了。

然而实际测试的时候,发现每次修改数据时,更新到cache的并不是最新数据,而是未修改前的旧数据,比如当前name="test0",修改为name="test1"点击保存后,更新到cache之中的确还是test0,再次修改为name="test2",更新到cache之中的确实test1。

百思不得其解~怀疑是model执行save时,本地有cache会延迟更新,于是在super.save和update_memcached_from_MysqL之间增加了time.sleep(10),并多次调用update_memcached_from_MysqL函数,可是依然是每次修改保存时,更新到cache的数据都是修改前的取值:

1     2         super(Application,1)">3         4         update_memcached_from_MysqL()5         time.sleep(106 7         time.sleep(108         update_memcached_from_MysqL()

想不出好的解决方案,猜测model真正将数据更新到数据的时机是在save整个函数执行结束后,臆测了如下更新逻辑:

1 子类save执行前2 父类save执行3 更新memcached4 子类save执行结束5 真正更新到数据库

于是必须想办法将第3步的cache更新逻辑挪到save执行结束后,然后要保证每次执行save *** 作时更新cache,这个位置又不能动~~

于是考虑通过开启独立线程异步执行的方式实现,改写update_memcached_from_MysqL,在其中开启独立线程执行一个delay版本的更新函数,线程start后会先休眠n秒钟(n为可控参数,下例中为2),而后才执行从数据库读取数据并更新到cache的逻辑,改完后手动更新数据多次,验证已经能拉取到最新数据。

1 def update_memcached_from_MysqL():2     """ 3     猜测由于model的缓存机制,save函数执行完成前,新的数据可能未及时更新到数据库,4     此处开启独立线程执行memcache更新 *** 作,线程中会休眠数秒再从数据库拉取最新数据更新5     """6     td = threading.Thread(target=update_memcached_from_MysqL_delay,args=(2,))7     td.start()

然而之前的更新流程还仅仅是猜测而已,虽然采用线程异步延迟更新cache的方法后,多次修改验证避开了取不到新数据的问题,并不就说明猜测一定是正确的,而且即便猜测是正确的,如果save函数执行完后,model的数据更新没有在线程延迟时间结束前完成,理论上还是会有问题,考虑可以通过设置一个定时任务,比如每隔10分钟定时执行cache更新逻辑,来保证新数据最多延迟10分钟也能生效。

本来想深入探究model save更新机制~然而最近太忙了~~blog都两周没更新了,初步尝试了一下也还没有研究清楚这一块save逻辑的源码,这个数据修改平台也仅供内部使用~~暂时先这么修补一下~~以后有时间再深究这一块的问题~~加入Todo List。

 

总结

以上是内存溢出为你收集整理的覆盖Django mysql model中save方法时碰到的一个数据库更新延迟问题全部内容,希望文章能够帮你解决覆盖Django mysql model中save方法时碰到的一个数据库更新延迟问题所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1157872.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-01
下一篇 2022-06-01

发表评论

登录后才能评论

评论列表(0条)

保存