上下文切换后,Python neo4j螺栓驱动程序失去连接

时间:2018-11-07 13:43:42

标签: python-3.x neo4j connection neo4j-bolt

我有一个用django编写的后端,它使用neo4j螺栓驱动程序与neo4j图形数据库进行通信。

每当我从最初建立连接的位置(例如,我在视图中打开连接,在信号中访问连接以及何时访问)时,使用Singleton来处理连接,并且螺栓驱动器会关闭连接。我尝试在视图中保存连接丢失的信息。)

我试图提取我提出的主要问题,并将其分解为下面的一小段示例代码。

我希望对行为做出任何解释,甚至可以更好地解决问题;)

from neo4j.v1 import Driver, GraphDatabase, basic_auth, Session, Transaction


def main():
    gm = GraphMapper()
    gm.begin_atomic_transaction()

    print(f"graph connection closed before method? {gm.is_connection_closed()}") # -> false

    fill_transaction() #the context switch

    print(f"graph connection closed after method? {gm.is_connection_closed()}") # -> true

    if not gm.is_connection_closed():
        print(f"graph connection open - try to commit") # -> is never called
        gm.commit_atomic_transaction_and_close_session()


def fill_transaction():
    gm = GraphMapper()

    print(f"graph connection closed in method? {gm.is_connection_closed()}") # -> true

    gm.create_update_node("TestNode")


class GraphMapper:
    __instance = None
    __transaction = None  # type: Transaction
    __session = None  # type: Session
    __connection = None # type: Connection
    __driver = None  # type: Driver

    def __new__(cls, *args, **kwargs):
        if not isinstance(cls.__instance, cls):
            cls.__instance = object.__new__(cls, *args, **kwargs)
        return cls.__instance

    def __init__(self):
        self.__driver = GraphDatabase.driver("bolt://localhost:7687", auth=basic_auth("neo4j", "password"))

    def is_connection_closed(self):
        return self.__transaction.session._connection._closed

    def begin_atomic_transaction(self):
        self.__session = self.__driver.session()
        self.__transaction = self.__session.begin_transaction()
        self.__connection = self.__transaction.session._connection
        return self.__transaction

    def commit_atomic_transaction_and_close_session(self):
        result = self.__transaction.commit()

        self.__transaction = None
        return result

    def create_update_node(self, label):
        # Add Cypher statement to transaction

实现细节:我有一个包装对象“ GraphMapper”,该对象封装了驱动程序的连接,会话和事务。并且被设计为一个单例实例。交易是在某个点(例如,一个视图)建立的,但我无法在此处完成交易。我需要从位置(B,例如post-save信号)中添加其他值。但是,我无法将对“ GraphMapper” A的引用传递给B。因此,我想到了如上所述的单例实现。 我已确保单例在所有位置(在一个请求内)完全相同。但是,当我通过方法调用退出上下文(包,类或方法)并在下一个位置检索“ GraphMapper”实例时,连接已关闭。我什至检查了对“ GraphMapper”及其连接的引用计数,垃圾收集器不应删除它。它很少说连接没有关闭。但是写入图形会导致连接被拒绝错误。

P.S .:我知道有一些无用和不必要的代码,这只是出于说明目的,我想确保垃圾收集器不会杀死某些对象。

0 个答案:

没有答案
相关问题