Go语言 什么使数据库池并发安全?

qfe3c7zg  于 11个月前  发布在  Go
关注(0)|答案(2)|浏览(93)

我最近使用了pgx库,它建议在并发期间使用连接池而不是按需创建连接。
由pgx.Connect()返回的 * pgx.Conn表示单个连接,并且不是并发安全的
以下理由是否足以支持上述说法?
1.池启动连接,并准备在请求时使用
1.确保数据库不会一次加载无限连接。
1.连接是线程安全的。
第1点和第2点是使用池的完美用例,不创建单个连接,但第3点(线程安全)也可以构建在常规连接中。
是否有其他货币的原因,为什么我们应该使用池,而不是创建对象的飞行?

umuewwlo

umuewwlo1#

以下理由是否足以支持上述说法?
1.如果配置正确,则为True。您可以设置一个连接数量不足的池。一旦连接耗尽,可以将更多请求设置为失败或等待-因此,连接将不再 * 准备好在请求时使用 *。
1.如果它是唯一的连接源,则为真。
1.就池而言,为True。您可以以非线程安全的方式使用从池中获取的连接。来自池的连接和使用pgx.Connect()设置的连接是相同的-如果您为多个线程提供给予相同的连接以共享,则它们可以互操作。
3(线程安全)也可以内置在常规连接中。
"Getting started"部分提到的线程安全可能是指如果多个操作员共享同一个连接会发生什么。如果不重新实现已经提供的会话隔离,就不能针对这些安全构建可靠的安全。示例包括:
1.工作者A开始一个transaction。在A工作的任何时候,工作者B都可以在A完成之前提交、回滚或使连接进入未定义状态。此外,在事务提交之前,共享连接的任何工作者的更改对其他任何人都不可见,而不是共享连接。
1.工作进程A sets会话或事务级别设置。工作进程B意外地受到它的影响,并且可以在任何时候突然取消设置或覆盖它。

  1. Worker A创建了一个temp对象。在同一个连接中操作,worker B共享相同的pg_temp命名空间,因此任何执行类似操作的尝试都会导致与数据库上A的临时对象的意外交互。
  2. Worker A发出一个长时间运行的查询。从worker B的Angular 来看,数据库没有响应-连接等待A请求的结果。
    任何session-level thing都会成为工作者之间潜在的摩擦点。也就是说,你可以想出一个不使用会话的线程不安全设施的工作流,并发现上面4引入的随机延迟是可以接受的。对于这些工作流,使用常规的线程安全设置仍然更安全,更可持续。
    是否有其他货币的原因,为什么我们应该使用池,而不是创建对象的飞行?
    在这种情况下,线程安全是通过让每个worker使用他们自己的会话/连接来保证的。你可以让每个worker总是开始建立自己的会话/连接,而不是请求一个新的、现成的、备用的连接,但这只是比较慢--池提前独立完成,节省了每个人建立、配置和稍后处理它们的时间。
    dbpool.QueryRow()将您的查询传递到一个刚从池中创建的干净连接,运行它并立即释放连接。两个并发线程可以共享一个池,并且保证它们的查询最终会在不同的连接中结束,而不会相互干扰。您不能将其用于依赖于transaction或discardable的任何东西。为此,您需要dbpool.Acquire(),保留已获取的连接,重复使用它来运行整个查询链,然后将conn.Release()返回到池中。
p1tboqfb

p1tboqfb2#

什么使数据库池并发安全?
是否有其他货币的原因,为什么我们应该使用池,而不是创建对象的飞行?
主要原因是由于这个库如何实现Conn:source
由于Conn的结构体成员和逻辑本质上是作用于单个请求的,因此池是更高阶的抽象,以保持这些对象新鲜,重置和重用而不重叠。否则像wbufpreparedStatements这样的东西将以预期的方式编写。

相关问题