使用 SQLAlchemy 的 PSQL 连接关闭时间延迟
PSQL connection closing time delay using SQLAlchemy
- 为什么调用
session.close()
和会话实际关闭之间似乎有明显的延迟?
- 我 "using up" 以一种感觉不对的方式建立联系。是否有更好的方法或我缺少的设计模式?
按照指南 here 我使用以下代码,为了完整性而复制:
@contextmanager
def session_scope():
"""Provide a transactional scope around a series of operations."""
session = Session()
try:
yield session
session.commit()
except:
session.rollback()
raise
finally:
session.close()
def run_my_program():
with session_scope() as session:
ThingOne().go(session)
ThingTwo().go(session)
这对于可靠地提交数据和避免无效会话非常有用。
问题在于达到连接限制。
例如,假设我有一个页面,每次访问进行 5 次异步调用。如果我访问该页面,并快速连续点击刷新,它将产生 5 * number_times_refreshed
个连接。它最终会关闭它们,但有一个不可忽略的时间延迟。
问题是使用 sessionmaker() 和绑定数据库引擎。具体这个不好办法:
def newSession():
engine = create_engine(settings.DATABASE_URL)
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()
return session
@contextmanager
def session_scope():
session = newSession()
try:
yield session
session.commit()
except:
session.rollback()
raise
finally:
session.close()
这会为每个请求创建一个新引擎。除了这是一个糟糕的模式之外,它还引起了 "connection" 被关闭的混淆。在这种情况下,我们有一个 "session" 和一个 "DBSession"。会话确实通过 session.close() 关闭,但这不会触及 "DBSession".
更好的方法(解决方案):
engine = create_engine(settings.DATABASE_URL)
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
@contextmanager
def session_scope():
session = DBSession()
try:
yield session
session.commit()
except:
session.rollback()
raise
finally:
session.close()
在应用程序的生命周期内创建一个连接
- 为什么调用
session.close()
和会话实际关闭之间似乎有明显的延迟? - 我 "using up" 以一种感觉不对的方式建立联系。是否有更好的方法或我缺少的设计模式?
按照指南 here 我使用以下代码,为了完整性而复制:
@contextmanager
def session_scope():
"""Provide a transactional scope around a series of operations."""
session = Session()
try:
yield session
session.commit()
except:
session.rollback()
raise
finally:
session.close()
def run_my_program():
with session_scope() as session:
ThingOne().go(session)
ThingTwo().go(session)
这对于可靠地提交数据和避免无效会话非常有用。 问题在于达到连接限制。
例如,假设我有一个页面,每次访问进行 5 次异步调用。如果我访问该页面,并快速连续点击刷新,它将产生 5 * number_times_refreshed
个连接。它最终会关闭它们,但有一个不可忽略的时间延迟。
问题是使用 sessionmaker() 和绑定数据库引擎。具体这个不好办法:
def newSession():
engine = create_engine(settings.DATABASE_URL)
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()
return session
@contextmanager
def session_scope():
session = newSession()
try:
yield session
session.commit()
except:
session.rollback()
raise
finally:
session.close()
这会为每个请求创建一个新引擎。除了这是一个糟糕的模式之外,它还引起了 "connection" 被关闭的混淆。在这种情况下,我们有一个 "session" 和一个 "DBSession"。会话确实通过 session.close() 关闭,但这不会触及 "DBSession".
更好的方法(解决方案):
engine = create_engine(settings.DATABASE_URL)
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
@contextmanager
def session_scope():
session = DBSession()
try:
yield session
session.commit()
except:
session.rollback()
raise
finally:
session.close()
在应用程序的生命周期内创建一个连接