我需要一个特定的业务场景,在一个实体(而不是PK)上设置一个来自序列的数字(序列必须是一个介于最小和最大之间的数字
我定义了这样的序列:
CREATE SEQUENCE MySequence
MINVALUE 65536
MAXVALUE 4294967296
START WITH 65536
INCREMENT BY 1
CYCLE
NOCACHE
ORDER;
在Java代码中,我从序列中检索数字,如下所示:
select mySequence.nextval from dual
我的问题是:
如果我在一个事务中调用这个“select mySequence.nextval from dual
”并且在另一个事务中同时调用相同的方法(并行请求),那么它确定序列返回的值是不同的吗?
不可能从第一个事务中读取未提交的值吗?
因为假设我没有使用序列和普通表,我会增加序列,然后如果trasactinalitY是默认的“READ COMMITTED”,事务2就能读取相同的值。
答案 0 :(得分:29)
答案是否定的。
Oracle保证序列生成的数字不同。即使发出并行请求,RAC环境或回滚和提交也是混合的。
序列与事务无关。
请参阅here the docs:
使用CREATE SEQUENCE语句创建一个序列,它是一个 数据库对象,多个用户可以从中生成唯一 整数。您可以使用序列自动生成主键 值。
生成序列号时,序列递增, 独立提交或回滚的事务。如果两个 用户同时递增相同的序列,然后递增序列 每个用户获得的数字可能有间隙,因为序列号是 由其他用户生成。一个用户永远无法获得 另一个用户生成的序列号。序列值后 由一个用户生成,该用户可以继续访问该值 无论序列是否由另一个用户递增。
序列号的生成与表格无关,因此相同 序列可用于一个或多个表。有可能的 单个序列号似乎会被跳过,因为 它们是在最终滚动的事务中生成和使用的 背部。此外,单个用户可能没有意识到其他用户 从相同的序列绘制。
答案 1 :(得分:7)
Oracle保证序列号不同。即使您的交易被回滚,也会使用该序列'而不是重新发布到另一个查询。
编辑:在需求周围添加其他信息"无间隙"在Cris的评论中说明了
如果您的要求是针对一系列数字无间隙那么oracle序列可能不是一个合适的解决方案,因为当事务回滚时,或者当数据库重新启动或任何其他时,将存在间隙场景数量。
序列主要用作唯一编号(例如主键)的高性能生成工具,而不考虑间隙和事务上下文约束。
如果您的设计/业务/审计要求需要考虑每个数字,那么您需要设计一个在事务上下文中使用预定数字的解决方案。这可能很棘手,并且在多线程环境中容易出现性能/锁定问题。最好尝试重新定义您的要求,以便差距不重要。
答案 2 :(得分:4)
sequence.nextval
永远不会为并发请求返回相同的值(在循环之前)。也许你应该检查以下网址:
http://docs.oracle.com/cd/B19306_01/server.102/b14220/schema.htm#sthref883
答案 3 :(得分:1)
不幸的是,你必须实现你自己的轮子 - 交易顺序。它非常简单 - 只需创建表格,如sequence_name varchar2,value,min_value number,max_value number,need_cycle char,并将'select value into sequence from变量等待表中的变量等待(或者nowait - 它取决于你的场景)'。在它发出update set value = variable from previous step + 1之后,其中sequence_name =序列的名称,并从客户端发出commit语句。就是这样。