0 CHN 08 5 数据库 自动批处理
Rickiewars edited this page 2023-04-12 17:23:04 +02:00
This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

English | 简体中文

自动批处理模式只对postgresql 14+版本的客户端库有效其他情况下会被忽略讲自动批处理之前先了解一下pipeline模式。

pipeline模式

从postgresql 14之后它的客户端库提供了pipelining模式接口在pipelining模式下新sql请求可以直接发送到服务端而不必等到上一个请求的结果返回这和HTTP的pipelining的概念一致详情请参考Pipeline mode。该模式对性能有很大的帮助,可以使较少的数据库连接就支持较大的并发请求。 drogon在1.7.6版本之后开始支持drogon会自动检查libpq是否支持pipeline模式如果支持的话通过drogon的DbClient发送的所有请求都是在pipeline模式下的。

自动批处理

默认情况下非事务客户端drogon为每个sql请求创建同步点即每个单独的sql语句都是一个隐式事务这可以保证sql请求之间相互独立这使得pipeline模式和非pipeline模式在用户看来是完全等价的。

不过每条sql语句创建一个同步点也有比较大的性能开销因此drogon提供了一种自动批处理模式在该模式下同步点的创建不再是每条sql之后都创建一个而是若干sql语句之后创建同一个链接创建同步点的规则如下

  • 一个EventLoop循环之内的最后一条sql之后必然创建同步点
  • 一个写数据库的sql之后创建同步点
  • 一个长sql之后创建同步点
  • 上一个同步点之后连续的sql语句数量达到上限的时候创建同步点

注意同一链接内两个同步点之间的sql相当于属于同一个隐式事务drogon没有提供显式的开启和关闭同步点的接口所以这些sql在逻辑上可能互不相关由于它们处于同一个事务中它们也会相互干扰因此该模式并不是完全安全的模式它有如下问题

  • 一个失败的sql会导致它之前的到上一个同步点之后的sql语句都发生回滚但用户并不会收到相关通知因为没有使用显式事务
  • 一个失败的sql会导致它之后的到下一个同步点之前的sql语句都返回失败
  • 写数据库的sql判别是靠简单的关键字匹配insertupdate等关键字这并不能涵盖所有的情况比如通过select调用了存储过程的情况因此虽然drogon努力减少自动批处理的负面影响但它不是绝对安全的

所以自动批处理模式对性能提高有一定帮助但它并不安全由用户自己决定在什么情况下使用它比如纯只读的sql使用自动批处理模式的DbClient。

注意 即使是只读的sql有时候依然会引起事务失败比如select超时因此它后续的sql也会受它影响而失败这对用户来说是可能是不可接受的因为在应用逻辑上它们可能互不相关所以严格来说自动批处理模式的应用场景应限制在只读且非关键的数据查询上。建议用户创建单独的自动批处理DbClient供这种sql使用。当然容易想到由自动批处理模式的DbClient生成的事务对象是可以放心使用的。

自动批处理的使能

当使用newPgClient接口创建客户端时把第三个参数设为true即可使能自动批处理模式 当使用配置文件创建客户端时把auto_batch选项设为true即可使能该客户端的自动批处理模式

09 插件