Common Lisp Mito DB 错误:与数据库服务器的连接丢失

问题描述 投票:0回答:1

我在一个 common Lisp 项目中使用 mito 来连接到 postgres 数据库。我有一个在数据库上运行多次的请求,并且收到以下两个错误:

  • DB Error: Connection to database server lost.
  • DB Error: This connection is still processing another query.

有没有办法在尝试执行查询之前检查是否找到与数据库的连接(又称为“未丢失”)?

有没有办法检查数据库连接是否正忙于执行另一个查询?如果是这样,我该如何等待它完成?类似于 JS 中的

await

连接丢失似乎是不正确的,因为如果后面的请求不是那么多,彼此距离不那么近,那么后面的请求就会起作用。

添加上下文:我正在一个 caveman2 项目中执行此操作,对于来自浏览器的给定会话,服务器可能会分配一个线程来处理特定路由,因此,该客户端的给定线程该路由的会话只能访问一个连接。我不确定这是否正确或导致此问题的原因。任何帮助将不胜感激!

common-lisp caveman2
1个回答
0
投票

对于来自浏览器的给定会话,服务器可能会分配一个线程来处理特定路由,因此,该路由的客户端会话的给定线程只能访问一个连接。

我认为这是对正在发生的事情的准确描述。

例外来自:cl-postgres/public.lisp:L328,在宏

using-connection
中,它在处理请求时禁止使用相同的连接。文档说:

这个 当您使用单个数据库时也可能会引发错误 来自多个线程的连接,但你根本不应该这样做。

正如 mito/issues/40 所暗示的,解决方案是在每个线程中使用

dbi:connect-cached

CL-DBI/连接池的文档说:

dbi:connect-cached 如果数据库已连接,则返回现有连接。由于将为每个线程创建一个缓存,因此在多线程应用程序中使用是安全的。

因此您可能有兴趣编写自己的包装宏,例如:

(with-db (db)
  ...)

展开为:

(let ((db (dbi:connect-cached ...)))
  ...)

如果以后您需要在主体周围添加更多代码,您可以更新宏,并且所有使用它的地方将在重新编译后更新。您可以为每个请求创建一个新连接,但在我看来,为每个请求创建一个线程和一个数据库连接可能无法很好地扩展,并且很容易受到 DDOS 攻击。也许您可以拥有一个工作人员池和一个数据库连接池。

© www.soinside.com 2019 - 2024. All rights reserved.