【问题标题】:Oracle Sequence nextval is jumping number back and forthOracle Sequence nextval 是来回跳数
【发布时间】:2014-08-17 21:57:31
【问题描述】:

我创建了一个新表和一个新序列,我有两个 C# Web 服务尝试使用 mySequence.nextval 使用相同的查询将记录插入此表(是的,我检查了很多次,它们都使用 mySequence.nextval)。

这两个 Web 服务正在向表中插入行,但 mySequence.nextval 正在返回无序的数字

这里是记录的创建方式,显示PrimaryKey,它的值来自mySequence.nextval

1 21 22 23 2 3 24 25 4 27 28 5

到目前为止没有重复,但为什么mySequence.nextval 来回跳跃?我应该担心吗

更新: 该序列是使用 cache_size = 20 创建的

【问题讨论】:

  • 为什么要对一个严肃的有效问题投反对票?

标签: c# sql database oracle sequence


【解决方案1】:

我敢打赌,您的数据库正在运行 RAC(Real Application Clusters)。假设是这种情况,并且您使用所有默认设置创建序列,这就是预期的行为。

默认设置是缓存 20 个值。默认情况下,RAC 集群中的每个节点都有一个单独的缓存。假设您有一个包含两个节点 A 和 B 的集群,第一次在 A 上请求 nextval,A 将缓存值 1-20 并返回值 1。如果下一次请求 nextval在 B 上,B 将缓存值 21-40 并返回值 21。从那里,您获得的值将取决于您的连接恰好在其上运行的节点。

一般来说,这应该不是问题。序列生成唯一编号。这些数字通常不需要是连续的。如果您确实需要按顺序返回值,因为您正在执行诸如按序列生成的值排序以确定“第一”或“最后”行,您可以在创建序列时使用 ORDER 子句来强制值要按顺序退回。但是,这对 RAC 数据库有负面的性能影响,因为它增加了节点之间为同步返回的值而需要进行的通信量。如果您需要确定“第一”或“最后”行,通常最好在表中添加datetimestamp 列并按其排序,而不是假设主键是按顺序生成的。

【讨论】:

  • 这就是原因,禁用序列缓存似乎正在修复它。我不担心对性能的影响非常小。
  • @DownMasters.com - 在创建序列时指定 ORDER 比将缓存设置为 1 更可取(您必须有一些缓存)。它的效率更高一些,并且可以保证按顺序返回值。从理论上讲,如果您将缓存设置为 1,则可能会出现乱序的值,除非您将序列创建为有序序列。我不知道缓存为 1 和指定 noorder 的序列实际上会乱序返回值的原因,至少在当前版本的 Oracle 中是这样。不过,这可能会在未来发生变化。
【解决方案2】:

来自文档...

序列号是独立于表格生成的,因此相同的序列可以用于一张或多张表格。个别序列号可能会被跳过,因为它们是在最终回滚的事务中生成和使用的。此外,单个用户可能没有意识到其他用户正在从同一序列中绘图。

http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_6015.htm#SQLRF01314

【讨论】:

  • 这是一个全新的表格和全新的序列,我 100% 确定没有人在其他地方使用这个序列
  • 真的吗? 100%确定?你有没有跟踪?您可能在不知情的情况下访问它。我以前做过。一些可视化工具运行将增加序列的查询。无论如何,我的观点是不要担心。如果您需要保证没有间隙,标准序列不是正确的工具。如果你使用序列,最终总会有差距。
  • 全新序列,我不会从其他任何地方访问它。
  • 然而,你是。您接受了另一个答案,该答案提供了有关您在何处访问它的详细信息,但这仍然是答案。如果他们愿意,人们可以花费他们的代表对此投票,但它只是缺乏细节。如果您接受的答案是正确的,这是您的问题。发生了多次访问,而您却不知道。
  • 与其说是缺乏细节,不如说只是回答了错误的问题。问题不是关于跳过的值,而是关于这些值出现的order。正确答案由贾斯汀提供。 /2c
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-24
  • 1970-01-01
  • 1970-01-01
  • 2020-09-26
  • 2018-12-11
  • 1970-01-01
  • 2019-08-29
相关资源
最近更新 更多