【问题标题】:Reusing database connection for multiple requests为多个请求重用数据库连接
【发布时间】:2017-03-21 14:32:57
【问题描述】:

如果我不需要事务,我可以为多个请求重用同一个数据库连接吗?

Flask 文档says:

因为数据库连接封装了一个事务,所以我们还需要确保每次只有一个请求使用该连接。

我是这样理解上面这句话的意思的:

Python DB-API 连接一次只能处理一个事务;要开始一个新事务,必须首先提交或回滚前一个事务。因此,如果我们的每个请求都需要自己的事务,那么每个请求当然都需要自己的数据库连接。

如果我弄错了,请告诉我。

但是假设我设置了自动提交模式,并在单个 SQL 语句中处理每个请求。或者,或者,假设我只读取而不是写入数据库。在任何一种情况下,似乎我都可以为我的所有请求重用相同的数据库连接,以节省多个连接的开销。但我不确定这种方法是否有任何缺点。

编辑:我可以看到我提议的一个问题:每个请求可能由不同的进程处理。由于连接应该probably not be reused across processes,让我澄清一下我的问题:我的意思是为每个进程创建一个连接,并将它用于恰好由该进程处理的所有请求。

另一方面,(绿色或本机)线程的全部意义通常是为每个线程提供一个请求,因此我提出的方法意味着跨线程共享连接。好像是one connection can be used concurrently in multiple native threads,但是not in multiple green threads

因此,具体来说,我的环境是带有多个多线程同步工作者的烧瓶 + gunicorn。

【问题讨论】:

    标签: python database web-applications flask


    【解决方案1】:

    根据@Craig Ringer comment on a different question,我想我知道答案了。

    连接共享的唯一可能优势是性能(其他因素 - 如事务封装和简单性 - 有利于每个请求单独连接)。而且由于无法跨进程或绿色线程共享连接,因此它只能与本机线程一起使用。但是psycopg2(可能还有其他驱动程序)不允许来自同一连接的并发访问。因此,除非每个请求都花费很少的时间与数据库通信,否则连接共享可能会影响性能,而不是受益。

    【讨论】:

    • 还有另一种可能需要共享连接的情况,那就是您希望不同的工作人员看到相同的脏(未提交)数据,或者共享会话状态,如 TEMPORARY 表、WITH HOLD 游标等。但这有点牵强。
    • @CraigRinger 但不同的工作人员是不同的进程(至少在 gunicorn 中),如果所有人共享相同的连接(并实际使用它),我认为它们会相互碰撞(根据引用的警告我的问题)。还是您的意思是可以使用锁来避免这个问题?
    • 如果它们是不同的进程,它们就不能共享连接。 (好的,所以如果你在没有 exec 的情况下分叉或将套接字传递给子进程,这是可能的,但只会导致混乱,它不会以任何有用的方式工作)。
    • @CraigRinger 这正是我的用例。你会建议怎么做?
    • @DylanYoung 如果我理解正确:运行一个线程,其工作是与数据库通信。 Broker 使用队列从其他线程向它请求,并使用队列传递回复。您可能希望将其包装在 Future 或类似中以使其成为更好的界面。发布一个新问题并在新问题中包含一个返回该问题的链接以获取详细信息,有人可能会解释。
    猜你喜欢
    • 2016-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-13
    相关资源
    最近更新 更多