Postgresql 为什么即使对象创建失败,Postgres序列项也会上升?

Postgresql 为什么即使对象创建失败,Postgres序列项也会上升?,postgresql,sequence,Postgresql,Sequence,我有一个Postgres项目,其中我的一个模型是客户机,只需按主键索引即可。我在创建客户机时遇到了一个问题,因为在创建客户机的过程中,有人在显式设置其主键时创建了一个客户机,我读到的主键不会影响Postgres的客户机序列表,该表负责在创建客户机对象时自动递增主键1 我运行了一些SQL查询来处理它,发现当前的序列值实际上比数据库263中客户机的最高id低1 262,因此它表示已经存在id为263的客户机。我尝试在前端应用程序中创建一个客户机,但再次出现错误,并决定重新运行查询。我看到数据库中没有

我有一个Postgres项目,其中我的一个模型是客户机,只需按主键索引即可。我在创建客户机时遇到了一个问题,因为在创建客户机的过程中,有人在显式设置其主键时创建了一个客户机,我读到的主键不会影响Postgres的客户机序列表,该表负责在创建客户机对象时自动递增主键1

我运行了一些SQL查询来处理它,发现当前的序列值实际上比数据库263中客户机的最高id低1 262,因此它表示已经存在id为263的客户机。我尝试在前端应用程序中创建一个客户机,但再次出现错误,并决定重新运行查询。我看到数据库中没有像预期的那样创建新的客户机,但我也注意到序列值确实上升到263,所以当我再次尝试创建客户机时,它工作了


即使相关模型的创建失败,PostgreSQL序列表也会递增,这是正常的行为吗?如果是这样的话,这可能会导致一些严重的问题。

是的,这是预期的行为:

下特瓦尔

将序列对象前进到其下一个值并返回该值。这是以原子方式完成的:即使多个会话并发执行nextval,每个会话都将安全地接收一个不同的序列值

如果已使用默认参数创建序列对象,则连续的nextval调用将返回从1开始的连续值。其他行为可以通过使用createsequence命令中的特殊参数获得;有关详细信息,请参见其命令参考页

重要提示:为了避免阻止从同一序列获取数字的并发事务,下一个操作永远不会回滚;也就是说,一旦获取了一个值,它就被认为已被使用,即使执行下一次调用的事务稍后中止。这意味着中止的事务可能会在分配的值序列中留下未使用的“漏洞”

请注意,
nextval
通常设置为自动增量/串行列的默认值

还要试着想象一下,如果
nextval
要回滚,会有多么困难和低效。基本上,您必须将每个客户机锁定在
nextval
上,直到整个事务(获得锁的那一个)处理完毕。在这种情况下,忘记并发插入

如果是这样的话,那似乎会引起一些严重的问题

像什么?您案例中的问题是有人手动为自动增量列指定了一个值。除非你是武士,否则你永远不应该那样做