我有一个Postgres项目,我的模型之一是Client,只需按其主键进行索引。我在创建客户端时遇到了问题,因为在某些情况下,有人创建了客户机,同时显式地设置了它的主键(我已经读过),它不会影响Postgres的客户端序列表,后者负责在创建客户端对象时自动递增主键1。
我运行了一些SQL查询来处理它,发现当前的序列值实际上比数据库263中客户端的最高id低1,262,所以它说ID为263的客户机已经存在。我尝试在前端应用程序中创建一个客户机,再次获得错误,并决定重新运行查询。我看到数据库中没有像预期的那样创建新的客户机,但我也注意到序列值确实上升到263,所以当我再次尝试创建客户机时,它工作了!
即使相关模型的创建失败,PostgreSQL序列表的这种正常行为是否也会增加?如果是这样的话,这似乎会引起一些严重的问题。
发布于 2018-06-01 19:41:22
是的,这是预期的行为。见文档
邻域 将sequence对象提升到其下一个值并返回该值。这是原子性的:即使多个会话同时执行nextval,每个会话都将安全地接收一个不同的序列值。 如果使用默认参数创建了序列对象,则连续的nextval调用将返回从1开始的连续值。其他行为可以通过使用CREATE sequence命令中的特殊参数获得;有关更多信息,请参见其命令参考页。 重要:为了避免阻塞从同一序列中获取数字的并发事务,nextval操作永远不会回滚;也就是说,一旦获取了值,就会被认为是使用的,即使随后执行nextval的事务会中止。这意味着中止的事务可能会在赋值顺序中留下未使用的“漏洞”。
注意,nextval通常被设置为自动增量/串行列的默认值。
同时,试想一下,如果nextval回滚的话,它将是多么的困难和低效。本质上,您必须锁定nextval上的每个客户端,直到整个事务(获得锁的事务)被处理为止。在这种情况下,忘记并发插入。
如果是这样的话,这似乎会引起一些严重的问题。
比如呢?在您的情况下,问题是有人手动指定了一个自动增量列的值。除非你是武士,否则你永远不应该这样做。:)
https://stackoverflow.com/questions/50650010
复制相似问题