我在APEX中创建了一个表,它有一个由SQL序列递增的PK:
CREATE SEQUENCE seq_increment
MINVALUE 1
START WITH 880
INCREMENT BY 1
CACHE 10这似乎工作得很完美。问题是,有时,通常当我早上起床并运行一个进程来输入新行时,它会跳过一堆数字。我只关心这些数字,因为在我的公司中,这些数字被用作文档的ID#,当这个工具上线时,丢失/跳过数字块将是不可接受的。
它似乎确实跳到了下一个'10‘数字。也就是说,昨天我的最后一次测试分配了883,今天早上它分配了890作为下一个数字。查看用于创建序列的代码,我注意到我已将其设置为缓存10个值,以便它的处理速度更快。有没有可能这个缓存在夜间被转储,它正在拉取890,因为它在缓存中有880-889,并且它被转储了?
是否还有其他潜在的原因和解决方案?
发布于 2011-09-28 22:27:40
序列不会也不能生成无间隙的值。所以你可能会认为这些数字偶尔会被跳过。当你使用序列时,这是非常正常的。
正如您所猜测的那样,最有可能的情况是,当APEX应用程序未被使用时,序列缓存一夜之间就会从共享池中老化出来。您可以通过声明您的序列NOCACHE来减少间隔的频率,但这会降低性能,而且不会消除间隔,它只会降低间隔的出现频率。
发布于 2011-09-28 22:30:45
Oracle序列永远不能保证是连续的。如果您需要一组绝对连续的值,则需要实现一个自定义解决方案。
在这种情况下,CACHE 10很可能就是您丢失数字的原因。缓存值是存储在内存中以备将来使用的序列值的数量。重新启动将清除缓存,并导致检索10个新值。类似地,如果序列使用的时间不够长,当前的值集可能会被清除出共享池,也会导致检索到一组新的值。
在您的实例中显然不是这种情况,但是序列号也可能由于回滚而丢失。涉及一个或多个序列的回滚事务将丢弃序列值。
发布于 2011-09-28 22:28:43
一些序列号已经从内存结构(我想是共享池?)中过期了。这是序列的预期行为。唯一的保证就是它们是唯一的。如果您需要呈现无间隙的序列,则必须在报告时使用rownum伪列。它是故意这样做的,否则你将不得不序列化所有的插入,即锁表。即使是这样,如果一个插入被回滚,也不能正常工作!
https://stackoverflow.com/questions/7584718
复制相似问题