sql - PostgreSQL 序列线程上的 setval nextval 增量是否安全?
问题描述
我想在 PostgreSQL 中将一个序列增加一些 batchSize,但我不确定这个查询对于对同一序列的并发调用是否安全。
select setval('my_sequence', nextval('my_sequence') + batchSize);
鉴于上面的查询,我担心的是,setval()
如果另一个线程同时获取了它,那么对序列的调用会将序列设置回来或者可能会中止查询nextval()
。
例如:
线程 1. nextval = 1001 batchSize = 100 将序列设置为 1101
Tread 2. nextval = 1002 batchSize = 20 将序列设置为 1022
这意味着序列最终可能会为 1002 到 1101 之间的 id 返回重复的 sequenceId。
使用该generate_series()
功能也可以实现相同的目的。缺点是不能保证该系列是按顺序排列的,因为其他线程可以同时调用nextval()
同一序列,这意味着我必须获取并解析生成的系列。
解决方案
来自PG 文档
为了避免阻塞从同一序列中获取数字的并发事务,nextval 操作永远不会回滚;也就是说,一旦获取了一个值,它就被认为是已使用的,并且不会再次返回。即使周围的事务稍后中止,或者调用查询最终没有使用该值也是如此。例如,带有 ON CONFLICT 子句的 INSERT 将计算要插入的元组,包括执行任何所需的 nextval 调用,然后再检测任何可能导致其遵循 ON CONFLICT 规则的冲突。这种情况会在赋值序列中留下未使用的“漏洞”。因此,PostgreSQL 序列对象不能用于获取“无间隙”序列。同样,如果事务回滚,setval 所做的任何序列状态更改都不会撤消。
我会假设上述状态是线程安全的。
推荐阅读
- python - 如何在 Python 中创建高斯混合模型?
- asp.net-mvc - @Helper razor 编码 html
- java - forEach 方法接受一个返回值的 lambda 表达式。为什么我没有收到以下代码的编译问题?
- javascript - 每次保存后如何自动运行 Webpack-dev-server?
- php - 用php替换前4个字符
- node.js - 如何使用 req.params.ids(多个 id)删除多个数据
- c++ - type_info 引用已删除的函数
- windows - 7-zip 安装和卸载后的 zip 错误
- python-3.x - 定义多个 Python 脚本中使用的常量
- python - Pandas/matplotlib 线图不显示 x 轴文本标签