Plone+SqlAlchemy+MySql中的未提交事务
我们有一个混合的web应用程序,它将MySql数据库与Plone集成。上一次升级是使用collective.tin、collective.lead和SqlAlchemy升级到Plone 4.0 好的,我知道collective.tin从未发布过,collective.lead已被取代;然而,从几年前开始,所有的事情都几乎完美地工作了 最近我们经历了一个非常奇怪的行为,正在寻求帮助以了解它 其中,我们有2个Plone内容类型,比如A和B,通过子类化collective.tin定义,以及相应的innodb MySql表;B行的外键指向a 在15-20分钟的时间跨度内,两个不同的用户创建了3个A对象和一些10-20B对象,这些对象没有提交到MySql,但被Plone索引;我使用linux shell中的MySql客户端执行的查询无法找到那些a行没有查找B行的查询;然而,这两个用户以及其他用户通过web应用程序执行的查询(上述组件堆栈)偶尔仍会找到并正确地可视化其中一些3A对象 只有在我重新启动Zope实例之后,才能从Plone web界面恢复正常活动;MySql数据库中仍然缺少3个A行和多个B行,但autoincrement计数器显示了预期的增量;我不得不从Plone索引中删除3个A对象的无效大脑,而B对象则不用担心Plone+SqlAlchemy+MySql中的未提交事务,mysql,sqlalchemy,plone,zope,Mysql,Sqlalchemy,Plone,Zope,我们有一个混合的web应用程序,它将MySql数据库与Plone集成。上一次升级是使用collective.tin、collective.lead和SqlAlchemy升级到Plone 4.0 好的,我知道collective.tin从未发布过,collective.lead已被取代;然而,从几年前开始,所有的事情都几乎完美地工作了 最近我们经历了一个非常奇怪的行为,正在寻求帮助以了解它 其中,我们有2个Plone内容类型,比如A和B,通过子类化collective.tin定义,以及相应的inn
关于可能的原因和如何调查问题有什么建议吗?我们在sqlalchemy 0.4中遇到了完全相同的问题;会话将与实际数据库内容不同步。在我们的例子中,这个问题多少被掩盖了,因为用户通过会话关联被发送到集群中的特定后端。如果亲和力突然丢失,消息就会消失。确切的细节有点模糊,因为我无法找到我所做的修复的正确的古代修订历史 从上下文中我可以了解到,会话标识映射可以防止会话需要数据库来存储以前检索到的对象。因此,它不会在不同的会话中看到对这些对象所做的更改 修复方法是在每次提交或回滚后调用会话上的.expire\u all;SQLAlchemy 0.5及以上版本在会话(我相信现在称为expire_on_commit)上自动执行autoexpire=True,但对于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()
我们在sqlalchemy 0.4中遇到了完全相同的问题;会话将与实际数据库内容不同步。在我们的例子中,这个问题多少被掩盖了,因为用户通过会话关联被发送到集群中的特定后端。如果亲和力突然丢失,消息就会消失。确切的细节有点模糊,因为我无法找到我所做的修复的正确的古代修订历史 从上下文中我可以了解到,会话标识映射可以防止会话需要数据库来存储以前检索到的对象。因此,它不会在不同的会话中看到对这些对象所做的更改 修复方法是在每次提交或回滚后调用会话上的.expire\u all;SQLAlchemy 0.5及以上版本在会话(我相信现在称为expire_on_commit)上自动执行autoexpire=True,但对于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()
使用了什么版本的sqlalchemy?sqlalchemy 0.4.8;由于我使用了collective.tin 0.3 svn/unreleased,我记得我无法使用更新版本的sqlalchemy;由于我使用了collective.tin 0.3 svn/unreleased,我记得我无法使用更新版本的sqlalchemy。非常感谢,Martijn!我还没有试过你的方法,但是,根据你写的,我也认为我们很幸运找到了一个愿意分享他在这个特定话题上的经验的人。非常感谢你,Martijn!我还没有尝试你的修复方法,但根据你所写的,我也认为我们非常幸运地找到了一个愿意分享他在这个特定话题上的经验的人。