Table of Contents
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.
自动批处理模式只对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判别是靠简单的关键字匹配(insert,update等关键字),这并不能涵盖所有的情况,比如通过select调用了存储过程的情况,因此虽然drogon努力减少自动批处理的负面影响,但它不是绝对安全的;
所以,自动批处理模式对性能提高有一定帮助,但它并不安全,由用户自己决定在什么情况下使用它,比如纯只读的sql使用自动批处理模式的DbClient。
注意 即使是只读的sql有时候依然会引起事务失败(比如select超时),因此它后续的sql也会受它影响而失败(这对用户来说是可能是不可接受的,因为在应用逻辑上它们可能互不相关),所以,严格来说,自动批处理模式的应用场景应限制在只读且非关键的数据查询上。建议用户创建单独的自动批处理DbClient供这种sql使用。当然,容易想到,由自动批处理模式的DbClient生成的事务对象是可以放心使用的。
自动批处理的使能
当使用newPgClient接口创建客户端时,把第三个参数设为true即可使能自动批处理模式; 当使用配置文件创建客户端时,把auto_batch选项设为true即可使能该客户端的自动批处理模式;
09 插件
Document
Tutorial
- Overview
- Install drogon
- Quick Start
- Controller
- Middleware and Filter
- View
- Session
- Database
- References
- Plugins
- Configuration File
- drogon_ctl Command
- AOP
- Benchmarks
- Coz profiling
- Brotli info
- Coroutines
- Redis
- Testing Framework
- FAQ