使用 SQLAlchemy 的 PSQL 连接关闭时间延迟

PSQL connection closing time delay using SQLAlchemy

按照指南 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()

在应用程序的生命周期内创建一个连接