ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Sequence使用细节两例

Sequence使用细节两例

原创 Linux操作系统 作者:realkid4 时间:2011-04-21 22:08:02 0 删除 编辑

 

OracleSequence对象是我们经常使用的一种生成唯一性数据序列的工具对象。数字类型列配合Sequence对象,可以方便的实现主键列功能。本片介绍使用Sequence对象时,需要关注的两个问题。

 

实验环境准备

 

首先构建一个实验的序列对象seq_t

 

//序列化对象

SQL> create sequence seq_t;

 

Sequence created

 

 

此时,seq_t的构建信息和默认值分别为。

 

--构造参数获取

 

-- Create sequence

create sequence SEQ_T

minvalue 1

maxvalue 999999999999999999999999999

start with 1

increment by 1

cache 20;

 

 

从默认值信息看,sequence对象相关的参数包括五个类型,分别表示sequence工作方式和当前信息。

 

ü        Minvalue:表示当前sequence所能够使用的最小值。

ü        Maxvalue:序列可以取到的最大值。如果序列类型是recycle的,则当前sequence重新回到minvalue

ü        Startwith表示下一次直接访问sequence对象时获取到的值;

ü        Cache是每次进行缓存的数据量;

 

 

关于Currvalnextval两个方法的使用

 

Sequence对象的两个方法seq_name.currvalseq_name.nextval分别用于访问指定sequence对象当前的sequence取值和获取一个新值。下面我们进行一系列的实验。

 

首先,开启会话一,注意此时sequence创建之后,并没有使用。Minvaluestart with值一样。

 

SQL> select sid from v$mystat where rownum<2;

 

       SID

----------

       147

 

select seq_t.currval from dual

 

ORA-08002: 序列 SEQ_T.CURRVAL 尚未在此会话中定义

 

 

注意,我们在这里看到了currval方法的一个特点。当在一个新的会话中,没有使用过nextvalue方法时,currval方法是不能调用的,调用是要报错ora-08002。报错提示信息声明说要求该序列在会话中进行声明,意味着currval是一个会话绑定的方法。

 

//第一次调用,

SQL> select seq_t.nextval from dual;

 

   NEXTVAL

----------

         1

//当在当前会话中调用过一次nextval之后,currval在紧接着的调用中就可以生效了;

SQL> select seq_t.currval from dual;

 

   CURRVAL

----------

         1

 

 

上面的实验,已经使我们获得了一个结论:sequence对象的currval方法是不能够单独调用的,在会话中一定要配合nextval方法之后,才能获取到刚刚调用的值;

 

下面继续开启另一个会话。

 

 

SQL> select sid from v$mystat where rownum<2;

 

       SID

----------

       153

 

SQL> select seq_t.currval from dual;

 

select seq_t.currval from dual

 

ORA-08002: 序列 SEQ_T.CURRVAL 尚未在此会话中定义

 

SQL> select seq_t.nextval from dual;

 

   NEXTVAL

----------

         2

 

SQL> select seq_t.currval from dual;

 

   CURRVAL

----------

         2

 

 

注意,虽然我们在会话一(sid=147)中使用了seq_t,并且使用了取值1,但是在另一个会话中,依然不能通过currval去获取到。说明currval方法是会话绑定,与sequence全局无关,必须与nextval配合使用。只有显示调用一次nextval之后,才能在会话中调用currval取值。

 

此时的sequence定义为:

 

 

-- Create sequence

create sequence SEQ_T

minvalue 1

maxvalue 999999999999999999999999999

start with 21

increment by 1

cache 20;

 

 

由于使用cache的原因,Oracle对当前seq_tstart with参数去定位21,出现跳号。这部分内容在后面详细介绍。

 

此时,我们回到会话一中,检查currval的情况。

 

SQL> select seq_t.currval from dual;

 

   CURRVAL

----------

         1

 

 

虽然我们在会话二中,已经将seq_t的取值推进到2。但是会话一还是记录着先前自己的1,没有同步推进。

 

结论:我们可以看到Currval使用的一个重要特征就是会话绑定特性。进入会话的时候,seq_t在当前会话是没有当前值的。只有在显示调用nextval方法之后,才会在会话内部保留一个取值。而这个取值是不会随着其他会话推进seq取值而更新的。

 

这也就是解释了currval方法受限制的方面。Currval方法是不能够真实反映sequence对象全局当前取值,而是会话内部上次调用的取值。这一点在开发过程中一定注意。

 

Cache参数

 

Cache参数是sequence对象的一个重要参数。Sequence是在Oracle并行访问系统中的一个串行单位,保证并行操作获取到的数值序列不会重合。本质上,sequence内部必然存在一种latch机制来保证其中的串行特性。

 

如果系统中广泛使用sequence,而且并发访问sequence的会话很多。那么必然存在频繁的latch现象,成为一种系统性能瓶颈。Cache参数就是解决这个问题的一种方案。

 

Cache的思路是这样。每次从要求访问Sequence数值,都是进行latch操作,每次不是只获取到一个数值,而是获取到Cache数量个数值存放在内存中。下次来访问获取新取值时,就不需要再次调用latch,而是分配内存中的数据值。这样就避免了过多的latch引发性能问题。

 

 

--刷新

SQL> alter system flush shared_pool;

系统已更改。

 

SQL> alter system flush buffer_cache;

系统已更改。

 

SQL> select sid from v$mystat where rownum<2;

       SID

----------

       147

 

SQL> select seq_t.nextval from dual;

   NEXTVAL

----------

        21

 

 

 

我们借助将内存flush之后,发现再次调用就出现了新的数字21,而不是3。这些就说明了缓存cache在起作用。将内存中的20个数字flush出之后,只能重新调用seq_t形成新值。

 

 

Cache机制缓解了latch系统争用的情况,但是随之而来的问题就是跳号问题。如果我们生成的sequence取值只是需要唯一不重复,发生跳号问题影响不大。如果数值具有一定的业务含义或者要求必须连续,我们就只能设置nocache参数情况了。

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/17203031/viewspace-693121/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
求道~

注册时间:2010-11-30

  • 博文量
    545
  • 访问量
    7753771