我有一个用 django 编写的后端,它使用 neo4j 螺栓驱动程序与 neo4j 图形数据库进行通信。
我使用单例来处理连接,并且螺栓驱动器关闭连接,每当我从最初建立连接的位置以外的其他位置访问它时(例如,我在视图中打开连接,在信号中访问它以及当我尝试保存在视图中连接丢失)。
我试图提取我提出的主要问题并将其分解为下面的一小段示例代码。
我将不胜感激对行为的任何解释,甚至更好的解决方案;)
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”,它封装了驱动程序的连接、会话和事务。并被设计为单例实例。事务在某个点(A,例如视图)建立,但我无法在此处完成事务。我需要从位置添加其他值(B,例如post-save
信号)。但是,我不能将对“GraphMapper”A 的引用传递给 B。因此,我想出了上面解释的单例实现。我已确保单例在所有位置(在一个请求中)都是完全相同的实例。但是当我通过方法调用退出上下文(包、类或方法)并在下一个位置检索“GraphMapper”实例时,连接已关闭。我什至检查了对“GraphMapper”的引用计数及其连接,垃圾收集器不应该删除它。很少有人说连接没有关闭。但是写入图表会导致连接被拒绝错误。
PS:我知道有一些无用和不必要的代码,这仅用于说明目的,我想确保垃圾收集器没有杀死某些对象。