按正确顺序获取下一个序列值



我在oracle数据库中有一个函数,它可以让我获得序列的下一个值。我也有以下PySpark代码:

def get_next_seq_value():
QUERY = "SELECT SCHEMA.GET_NEXT_SEQ_VALUE FROM DUAL"
sqlContext.clearCache()
next_seq_value_df = sqlContext.read.format("jdbc").options(url=URL, driver=DRIVER, QUERY=QUERY, user=USER, password=PASSWORD).load().unpersist()
next_seq_value = next_seq_value_df.take(1)[0][0]
return next_seq_value

我从这里调用这个函数:

array = []
for each_item in df_list:
next_seq_value = get_next_seq_value().encode('utf-8').strip()
array.append(next_seq_value)

问题如下:

当我运行以下命令时,数组看起来是这样的:

[' 545671 ', ' 545672 ', ' 545673 ', ' 545694 ', ' 545695 ', ' 545696 ']

为什么我看不到545674和545675…它只是跳到'545694'。如何确保按顺序调用函数?

默认顺序缓存大小为20:

如果省略CACHE和NOCACHE,则数据库默认缓存20个序列号。

所以看起来像是在你的呼叫之间的另一个称为nextval的会话。

此外,从你的代码QUERY = "SELECT SCHEMA.GET_NEXT_SEQ_VALUE FROM DUAL"看起来像你包装your_sequence.nextval到函数GET_NEXT_SEQ_VALUE。这里看起来有点小题大做:你会得到额外的调用(SQL->PL/SQL->调用.nextval())和这里的开销。您可以只使用select seq.nextval from dual:x := seq.nextval;。如果想生成N个值,可以使用:select seq.nextval from dual connect by level<=20;

完全同意前面两个答案。我不确定您使用的是哪种类型的数据库架构,但我也想指出,使用Oracle RAC,每个集群节点实例也将有一个单独的序列缓存。

,

node 1: sequence cache 101-120
node 2: sequence cache 121-140
node 3: sequence cache 141-160

因此,根据碰巧处理请求的节点,nextval也可能不是按顺序排列的。

关键是,当使用序列时,您应该只计算唯一的值,而不一定没有间隔(消除缓存会严重影响性能),甚至不一定按顺序排列,这取决于您的物理服务器架构。如果要保持事情的顺序,无论什么是重要的,除了顺序计数器之外,还可以在记录中添加时间戳。

您的问题显然是而不是顺序错误*序列生成IDs,但间隙.

当你决定使用序列时,通常必须计算间隙.

如果您使用默认的缓存大小为20,那么您将在每个会话结束时平均丢失10IDs。

你可以用NOCACHE来减少这个,但即使在这里,你调用nextval,然后回滚事务,这个ID可能会丢失。由于下一个事务通常以新的nextval开始…

最新更新