我一直在浏览 psycopg2 文档以了解它如何处理事务等等。
我发现事务是在连接级别上创建的,无论您使用什么游标,会话对所有人都是可见的。
警告 默认情况下,即使是一个简单的 SELECT 也会启动一个事务:在长时间运行的程序中,如果不采取进一步的操作,会话将保持“事务中空闲”状态,由于多种原因,这是一种不希望的情况(锁由会话,桌子膨胀......)。对于长期存在的脚本,请确保尽快终止事务或使用自动提交连接。
所以我想知道高流量API将如何处理这个问题,以避免出现奇怪的情况,即由于完成了不同的API请求并且共享会话而提交或回滚多个查询......一切都落在同一个内部交易。
连接池似乎是答案,但连接数量仍然有限,因此如果将池中的相同连接提供给不同的 API 请求,实际上您可能会遇到相同的问题。
是否有一个足够大的池来降低连接被两个不同进程共享的风险,或者我是否遗漏了它是如何工作的?
提前致谢^^抱歉问了这么长的问题。
连接池确实是答案,原因如下:
如Psycopg2 池文档中所述:
getconn(键=无) 从池中获取免费连接。
这里要强调的是“免费”这个词。 基于一个
不同的问题我去图书馆查看如何从池中检索连接:
def _getconn(self, key=None):
"""Get a free connection and assign it to 'key' if not None."""
if self.closed:
raise PoolError("connection pool is closed")
if key is None:
key = self._getkey()
if key in self._used:
return self._used[key]
if self._pool:
self._used[key] = conn = self._pool.pop()
self._rused[id(conn)] = key
return conn
else:
if len(self._used) == self.maxconn:
raise PoolError("connection pool exhausted")
return self._connect(key)
Psycopg2 保留可用连接和正在使用的连接的列表。因此,正如评论中提到的,它确实为您提供了“免费”连接。每个 API 请求都会有自己独立的事务,因为它们每次都会收到一个免费连接。
需要考虑的事项 请记住,数据库对打开连接有其自己的限制:
最大连接数(整数) 确定与数据库服务器的最大并发连接数。默认值通常为 100 个连接,但如果您的内核设置不支持它(在 initdb 期间确定),则可能会更少。该参数只能在服务器启动时设置。 (来自:Postgres 文档
)如果您的 API 根据需求进行扩展,请考虑在服务器端设置 maxconn,因为所有 API 实例之间将共享相同的 100 个可用端口。
感谢@snakecharmerb 和@AdrianKlaver,他们的评论让我找到了答案。