【问题标题】:nextval and curval confusion in PostgreSQLPostgreSQL 中的 nextval 和 curval 混淆
【发布时间】:2011-05-10 08:52:36
【问题描述】:

如果多个用户同时运行以下查询会发生什么?

INSERT INTO "Retail"."Attributes"("AttributeId","AttributeCode","AttributeName")
VALUES(nextval('"Retail"."CompoundUnits_CompoundUnitId_seq"'::regclass),'COL','Color');

INSERT INTO "Retail"."AttributeDetails"  
  ("AttributeId","AttributeDetailCode","AttributeDetailName")
VALUES
(
  currval('"Retail"."CompoundUnits_CompoundUnitId_seq"'::regclass), 'COL-Red', 'Color Red'
),
(
  currval('"Retail"."CompoundUnits_CompoundUnitId_seq"'::regclass), 'COL-Blu', 'Color Blue'
), 
(
  currval('"Retail"."CompoundUnits_CompoundUnitId_seq"'::regclass), 'COL-Gre', 'Color Green'
);

这种方法是否像 SQL SERVER 的 SCOPE_IDENTITY() 一样可靠?任何建议将不胜感激。

【问题讨论】:

标签: sql-server postgresql scope-identity nextval


【解决方案1】:

currval() 是特定于会话的。如果一个单独的会话增加了您的序列,currval() 将继续返回您的预期值。

也就是说你可能想使用insert returning:

insert into foo values (...) returning id;

insert into bar (foo_id, ...) values (:id, ...),  (:id, ...), ...;

【讨论】:

    【解决方案2】:

    基于文档 - '多个会话保证分配不同的序列值'

    因此,您将获得不同的值,但取决于创建序列对象时指定的“缓存”设置,跨多个并发会话获得的值可能并不总是连续的。 阅读sequences 上的文档,尤其是“缓存”参数。

    【讨论】:

      【解决方案3】:

      你对 currval 的使用完全没问题

      我不知道 SCOPE_IDENTITY() 所以我无法比较这两个概念。

      顺便说一句:您的声明中不需要演员表:

      currval('"Retail"."CompoundUnits_CompoundUnitId_seq"')

      够了

      【讨论】:

      • 不是,您不必关闭自动提交。 currval 在交易之外是完全安全的
      • +1 斯科特。 currval() 是为会话初始化的,并且是并发安全的。这就是您不能在使用 nextval() 或 setval() 之前调用它并相应设置布尔标志的原因。
      • 序列真的很让人头疼。它们是事务安全的,因为它们独立于所有事务语义,有点生活在它们之外。当我开始时,我花了一些时间来了解它们。
      猜你喜欢
      • 2018-12-11
      • 2013-03-30
      • 1970-01-01
      • 2010-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-12
      • 2016-07-11
      相关资源
      最近更新 更多