2

我刚刚开始使用新的用于 python 的 neo4j 驱动程序并且完全被事务卡住了。如何检查交易是否成功完成?据我所知,commit函数不会自动引发任何错误,例如,如果我向它提供了不正确的 Cypher 查询,我不会得到任何信息。

我尝试从对象中读取last_result参数Session并想出了类似的东西:

import neo4j.v1 as neo

def db_confirm_transaction_success(session):
    try:
        w = list(session.last_result)
        return True
    except neo.CypherError as e:
        session.last_result._consumed = True
        return False
    except neo.ResultError as e:
        session.last_result._consumed = True
        return False

它有点工作......然而,它确实需要修改私有属性,而且看起来并不正确/正确。必须有一个更简单、更优雅的解决方案。

提前感谢您的帮助。

编辑:只是为了明确Transaction.success表示事务是否应该提交或回滚。然而,例如,Cypher 错误可以晚于查询的执行时间来识别。

4

1 回答 1

6

在阅读开发人员手册之前,我一直在努力解决同样的问题。

在那之前,我无法弄清楚为什么运行几个错误的语句session.run(statement)不会引发异常,而是会引发异常session.close()

然后我尝试使用类似的东西:

with session.begin_transaction() as tx:
    tx.run(statement)
    tx.success = True

如果您不想要上下文管理器,可以使用:

tx = session.begin_transaction()
tx.run(statement)
tx.commit()

如果您阅读python 文档,您可能会注意到tx.commit()与运行tx.success=Truetx.close().

问题在于,调用commit()只会将密码消息附加COMMIT到连接的流中。据我所知,它不能验证交易是否成功。


在阅读了手册中的第 18 节后,我发现因为我没有显式地消费结果,所以无法保证语句被处理,因为库使用了延迟加载(仅按需检索结果)。请参阅下面 18.1 中的注释:

“当光标在流中移动时,结果记录会延迟加载。这意味着必须将光标移动到第一个结果才能消费该结果。这也意味着必须在摘要信息和元数据之前显式消费整个流可用。通常最好的做法是显式使用结果并关闭会话,尤其是在运行更新语句时。即使不需要摘要信息,这也适用。未能使用结果可能会导致不可预知的行为,因为无法保证服务器已经看到并处理了 Cypher 语句。”


因此,本质上,您需要在运行 cypher 语句后显式使用您的结果。这可以这样做:

res = session.run(statement) # or the equivalent iusing transaction style
res.consume()

我注意到迭代所有结果的.consume()函数调用(StatementResult 类定义了一个方法)。所以,虽然我没有测试过它,但可能只是简单地循环结果会为你消耗:list(self)__iter__

res = session.run(statement)
for r in res:
    continue

希望这会有所帮助!

于 2016-08-25T19:12:16.620 回答