Neo4j驱动程序-确认交易成功



我刚刚开始使用python的新neo4j驱动程序,但完全被事务所困扰。如何检查交易是否成功完成?就我所能说的,commit函数不会自动引发任何错误,例如,如果我向它提供了一个不正确的Cypher查询,我就得不到任何信息。

我试着从Session对象中读取last_result自变量,并想出了一些类似的东西:

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错误可以被识别为查询执行时间较晚。

在阅读开发人员手册之前,我一直在做同样的事情。

在那之前,我不明白为什么用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语句。">


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

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

我注意到.consume()函数调用list(self)来迭代所有结果(StatementResult类定义了一个__iter__方法)。因此,虽然我还没有测试过它,但可能是这样的情况,即简单地在结果上循环会为您带来消耗:

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

希望这能有所帮助!

只是想发布Neo4j 4.x的更新答案。

def commit_data(query):
with driver.session(database="neo4j") as session:
tx = session.begin_transaction()
result = tx.run(query)
result = [dict(i) for i in result]

# uncomment below line to see the complete txn summary.
# print(result) 
if result[0]['failedOperations']>0:
print(query)
print(result)
raise 'Error! Please recheck your query.'

tx.commit()

希望它能帮助其他人。

最新更新