Oracle序列事务性

时间:2012-08-24 06:45:17

标签: java sql oracle hibernate sequence-sql

我需要一个特定的业务场景,在一个实体(而不是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就能读取相同的值。

4 个答案:

答案 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语句。就是这样。