postgresql - 表 xxx 上的 UPDATE 语句预期更新 1 行; 0 个与 Zope transactionmanager 匹配

标签 postgresql sqlalchemy pyramid zope transactionmanager

我正在运行 Pyramid + Zope 事务管理器 + SQLAlchemy + PostgreSQL。在某些情况下,我在 Pyramid Web 应用程序上看到 StaleDataError 错误,这应该是更新数据库中一行的非常简单的 View 。由于错误发生在正常 View 边界之外并且不可重复,因此调试起来非常棘手。

我想这可能与断开的数据库连接或事务生命周期有关。但是我不知道如何开始调试系统,所以我想问是什么导致了这种情况,以及如何确定这样的错误。

表 'xxx' 上的 UPDATE 语句预期更新 1 行; 0 个匹配。

Stacktrace (most recent call last):

  File "pyramid/tweens.py", line 20, in excview_tween
    response = handler(request)
  File "pyramid_tm/__init__.py", line 94, in tm_tween
    reraise(*exc_info)
  File "pyramid_tm/compat.py", line 15, in reraise
    raise value
  File "pyramid_tm/__init__.py", line 82, in tm_tween
    manager.commit()
  File "transaction/_manager.py", line 111, in commit
    return self.get().commit()
  File "transaction/_transaction.py", line 280, in commit
    reraise(t, v, tb)
  File "transaction/_compat.py", line 55, in reraise
    raise value
  File "transaction/_transaction.py", line 271, in commit
    self._commitResources()
  File "transaction/_transaction.py", line 417, in _commitResources
    reraise(t, v, tb)
  File "transaction/_compat.py", line 55, in reraise
    raise value
  File "transaction/_transaction.py", line 389, in _commitResources
    rm.tpc_begin(self)
  File "/srv/pyramid/trees/venv/lib/python3.4/site-packages/zope/sqlalchemy/datamanager.py", line 90, in tpc_begin
    self.session.flush()
  File "sqlalchemy/orm/session.py", line 2004, in flush
    self._flush(objects)
  File "sqlalchemy/orm/session.py", line 2122, in _flush
    transaction.rollback(_capture_exception=True)
  File "sqlalchemy/util/langhelpers.py", line 60, in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
  File "sqlalchemy/util/compat.py", line 182, in reraise
    raise value
  File "sqlalchemy/orm/session.py", line 2086, in _flush
    flush_context.execute()
  File "sqlalchemy/orm/unitofwork.py", line 373, in execute
    rec.execute(self)
  File "sqlalchemy/orm/unitofwork.py", line 532, in execute
    uow
  File "sqlalchemy/orm/persistence.py", line 170, in save_obj
    mapper, table, update)
  File "sqlalchemy/orm/persistence.py", line 692, in _emit_update_statements
    (table.description, len(records), rows))

最佳答案

这是最有可能的情况:

您有 2 个请求,首先选择一个对象并尝试在数据存储区中更新/删除它,最终出现“竞争条件”。

假设您想做一些事情,比如获取一个对象然后更新它。

如果事务需要一些时间并且您没有选择带有“for update”的对象从而锁定行 - 如果对象在第一个请求中被删除并且第二个事务试图对数据库中不再存在的行发出更新您最终可能会遇到此异常。

您可以尝试进行一些行锁定以防止这种情况发生 - 后续事务将“等待”第一个操作完成。在执行之前。

http://docs.sqlalchemy.org/en/rel_1_0/orm/query.html?highlight=for_update#sqlalchemy.orm.query.Query.with_for_update

http://docs.sqlalchemy.org/en/rel_1_0/orm/query.html?highlight=with_lockmode#sqlalchemy.orm.query.Query.with_lockmode

描述一些可以用来解决这个问题的 sqlalchemy 机制。

关于postgresql - 表 xxx 上的 UPDATE 语句预期更新 1 行; 0 个与 Zope transactionmanager 匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30763961/

相关文章:

python - 具有继承性的 SQLAlchemy 自省(introspection)列类型

python - 如何做 Pylons/Pyramid 插件系统?

python - Pyramid :如何获取刚刚创建的数据库行的 ID?

postgresql - pgAdmin III 大师提示 - 服务器未监听

postgresql - DBeaver 只能看到连接中的默认 PostgreSQL 数据库

java - 2019年客户端-服务器之间的高效数据库同步

python - 为什么PIP将下划线转换为破折号

sql - 将相同的 id 分配给具有相同数据组合的行

python - SQLAlchemy : Column name on union_all

python - 使用 SQLAlchemy 的动态 column_property