我们有一个使用collective.tin、collective.lead和SqlAlchemy的混合web应用程序,集成了MySql数据库和Plone (上次升级到Plone 4.0)。
好吧,我知道collective.tin从来没有发布过,collective.lead已经被取代了;然而,自从几年以来,所有的东西都(几乎)完美地工作着。
最近,我们经历了一个非常奇怪的行为,为了理解它,我们正在寻求帮助。
其中,我们有两个Plone内容类型,比如A和B,通过对collective.tin进行子类化来定义,以及相应的innodb MySql表;B的行有一个指向A的外键。
在15-20分钟的时间跨度内,两个不同的用户创建了3个A对象和一些10-20个B对象,这些对象没有提交到MySql,但由Plone索引;我在linux shell中使用MySql客户端执行的查询无法找到这些A行(没有查找B行);但是,这两个用户以及其他用户通过web应用程序(前面提到的组件堆栈)执行的查询偶尔仍然可以找到并正确可视化其中的一些A对象。
只有在我重启Zope实例后,才有可能从Plone web界面恢复正常活动;MySql db中仍然缺少3个A行和许多B行,但自动增量计数器显示了预期的增量;我必须从Plone索引中删除3个A对象的无效大脑(不用担心B对象)。
对可能的原因和如何调查问题有什么建议吗?
发布于 2013-01-11 22:00:41
我们在sqlalchemy 0.4中遇到了完全相同的问题;会话将与实际数据库内容不同步。在我们的案例中,这个问题在某种程度上被掩盖了,因为用户通过会话亲和性被发送到集群中的特定后端。如果亲和力突然消失,消息就会消失。确切的细节有点模糊,因为我找不到我放置的修复的正确(古老)修订历史。
从上下文中我可以收集到的信息是,会话标识映射防止了会话需要数据库来获取它之前检索到的对象。因此,它不会看到在不同会话中对这些对象所做的更改。
修复方法是在每次提交或回滚之后调用会话上的.expire_all();SQLAlchemy 0.5和更高版本会自动执行此操作(会话上的autoexpire=True,我相信现在称为expire_on_commit ),但是对于0.4,您需要注册一个SessionExtension来为您完成此操作。
幸运的是,我们在这个项目中也使用了collective.lead,所以我的解决方案就是您的解决方案:
# The identity map should be flushed on commit.
# SQLAlchemy 0.5 does this properly, but in 0.4 we need to do this via
# a SesssionExtension.
from sqlalchemy import __version__
if __version__[:3] == '0.4':
from sqlalchemy.orm.session import SessionExtension
class ExpireAllSessionExtension(SessionExtension):
def after_commit(self, session):
"""Expire the identity-map on commit"""
session.expire_all()
def after_rollback(self, session):
"""Expire the identity-map on rollback"""
session.expire_all()
def installExtension():
# Patch collective.lead.database to let us install the extension
# on the session created there.
from collective.lead.database import Database
old_session = Database.session.fget
def session(self):
session = old_session(self)
if session.extension is None:
session.extension = ExpireAllSessionExtension()
return session
Database.session = property(session)
else:
def installExtension():
pass定义映射器时,使用以下命令安装此扩展:
from .sessionexpiration import installExtension
# Ensure that sessions get properly expired on commit and rollback.
installExtension()https://stackoverflow.com/questions/14276522
复制相似问题