【问题标题】:Sqlalchemy query returns incorrect and outdated results (for sqlite engine)Sqlalchemy 查询返回不正确和过时的结果(对于 sqlite 引擎)
【发布时间】:2013-09-12 02:19:04
【问题描述】:

我正在将 sqlalchemy 与 sqlite 引擎(开发服务器)一起使用,并且刚刚发现在更新查询之后,下一个 web 请求中的查询返回过时的数据集(这取决于哪个线程用于请求,据我了解是一个线程池)。

我正在使用 scoped_session 和文档中的其他推荐内容 (DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension())))。

这里是 Web 请求的示例以及在那里执行的内容。

request-1:thread-1: SELECT * FROM table WHERE id=1 -> (id:1, data:1)
request-2:thread-2: UPDATE table SET data=2 WHERE id=1; COMMIT
request-3:thread-1: SELECT * FROM table WHERE id=1 -> (id:1, data:1) // STILL data:1 !
request-4:thread-4: SELECT * FROM table WHERE id=1 -> (id:1, data:2) // NEW DATA!     
request-5:thread-1: SELECT * FROM table WHERE id=1 -> (id:1, data:1) // AND AGAIN OLD DATA!

这是什么?我怎样才能避免这种行为?在上面的示例中,所有 Web 请求都按连续顺序执行,因此 SQL 查询不会相交。

【问题讨论】:

    标签: python sqlite sqlalchemy pyramid


    【解决方案1】:

    您可以使用要获取其值的数据库对象发出Session.refresh

    【讨论】:

    • 不,不起作用,但它给了我一个提示,也许 sqlalchemy 认为该线程中的连接处于事务状态。
    • 我有一个建议,在 Web 请求处理程序的开头获取 dbsession 实例后执行transaction.commit(),总是如此。这对我来说很有帮助,但我仍然不明白 sqlalchemy(或者可能是 sqlite)是如何处理事务的。
    • @SergeyStolyarov 好吧,我通常会在开始任何可能最终更改数据库的过程之前自己做。
    • 在我的情况下,如果我在 SELECT 之前不这样做,我会得到过时的数据。我觉得很奇怪,那里的交易有问题。
    【解决方案2】:

    您需要激活pyramid_tm 补间。

    [app:main]
    
    pyramid.includes =
        pyramid_tm
    

    tween 在每次请求后提交事务,当有新请求进入时隐式启动 new 事务。

    当你不启动新事务时,事务将看不到其他事务(线程)中提交的数据;这是数据库事务的固有特性,因为不这样做会导致不一致错误。

    【讨论】:

    • 谢谢,我想过,但对我来说它看起来有点过分。基本上我确实需要在每个请求上启动事务,但不需要在请求完成时自动提交/中止它。
    • 开始一个事务要求你先结束前一个事务。当没有写入发生时,事务提交无论如何都很便宜。
    • 好的,刚刚添加了pyramid_tm,启用了tm.commit_veto,但是如果我发送4xx 状态,我在日志中看不到任何ROLLBACKABORT 消息。可以吗?顺便说一句,手动transaction.abort() 调用也不调用ROLLBACK
    • transaction 动作不是 SQL 命令;没有 connection.execute('ABORT') 或 `connection.execute('ROLLBACK') 正在执行;这是一个连接级别的方法。
    • 我明白这一点,如果我手动执行dbsession.rollback(),我会看到相应的消息 (ROLLBACK)。那么我如何确定transaction.abort() 真的有效呢?当然,我可以启用 txn。记录器并查看类似2013-09-09 17:38:52,334 DEBUG [txn.140227417442048][Dummy-2] abort 的内容,但为什么没有来自 db 引擎的任何相关消息?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-07
    相关资源
    最近更新 更多