【问题标题】:When session.flush() failed on SQLAlchemy, should I call rollback?当 SQLAlchemy 上的 session.flush() 失败时,我应该调用回滚吗?
【发布时间】:2015-11-25 03:13:23
【问题描述】:

我知道当session.commit() 失败时调用回滚,例如try-except 块。
但是当session.flush()失败时,我应该执行rollback()吗?

try:
    session.flush()
except IntegrityError:
    session.rollback()

【问题讨论】:

    标签: python mysql postgresql sqlalchemy


    【解决方案1】:

    刷新失败总是回滚,不需要自己动手:

    http://docs.sqlalchemy.org/en/latest/orm/session_api.html#sqlalchemy.orm.session.Session.flush

    数据库操作将在当前事务上下文中发出并且不影响事务的状态,除非发生错误,在这种情况下整个事务被回滚。您可以在事务中尽可能频繁地刷新(),以将更改从 Python 移动到数据库的事务缓冲区。

    【讨论】:

    • 如果会话没有配置 autocommit=True,你绝对确实需要在刷新失败后显式回滚你的事务,否则你的会话将处于不可用状态(这里的另一个答案是正确的)。
    【解决方案2】:

    接受的答案并不完全正确。关于Session.flush() 的文档对此有点误导。

    一旦失败,事务(即数据库事务)将被回滚(由数据库)。它的python对应物Session对象本身将处于“非活动”状态,并且根据文档12

    必须由调用应用程序显式回滚,就像在未发生故障时需要显式提交一样。

    它确实进一步承认

    这是使用 ORM 时的常见错误

    【讨论】:

    • 我刚遇到这个。如果我理解正确,session.rollback 只会影响 Python 端。如果事务刷新成功,回滚对数据库没有影响,对象/行仍然存在于其中。例如,如果您刷新但未提交,您将生成一行id=1。下次刷新时,自动增量将为 2,即使您已回滚。如果我错了,请纠正我。
    • @barakbd 刷新会话时,它会与数据库事务通信,会话中的哪些更改必须在事务内部应用。例如,如果创建并刷新了新的会话对象,它会指示 db 事务创建具有新 ID 的新行。提交会话时,它指示 db 事务提交更改(并关闭事务)。 session.rollback 还回滚 db 事务。 ID 确实不会跨事务回收。
    • 这就是我创建单个会话、设置 autoflush=False 并且仅在所有模型成功填充后才提交的原因。 ORM relationship 消除了在模型实例化期间为外键生成 ID 的需要。
    猜你喜欢
    • 1970-01-01
    • 2012-08-19
    • 2012-12-02
    • 1970-01-01
    • 2011-12-31
    • 2010-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多