请考虑以下代码:
create sequence "s" cache 50;
select "s".nextval from dual;
当我执行上述一次时,我得到了
NEXTVAL
-------
1
当我执行两次语句时,除了DDL语句上的明显错误消息之外,我正在
drop sequence "s";
create sequence "s" cache 50;
select "s".nextval from dual;
create sequence "s" cache 50;
select "s".nextval from dual;
NEXTVAL
-------
51
运行语句三次以获得:
drop sequence "s";
create sequence "s" cache 50;
select "s".nextval from dual;
create sequence "s" cache 50;
select "s".nextval from dual;
create sequence "s" cache 50;
select "s".nextval from dual;
NEXTVAL
-------
101
如果发生系统故障,则所有未在已提交的DML语句中使用的缓存序列值都将丢失。
但是,失败的DDL语句是否有资格成为系统故障?这种行为的原因是什么?
答案 0 :(得分:6)
当我们第一次执行 DDL (CREATE SEQUENCE SEQ1 CACHE 50
)时,会在v$DB_OBJECT_CACHE
中输入一个条目。
在您获取序列值之前,您会注意到shareable_mem
列没有条目存储对象使用的共享池中的可共享内存量。一旦获取序列的下一个值(第一次),您就会注意到此shareable_mem
列有一个值(Oracle在共享池中分配内存)。
当我们重新执行DDL(相同的语句)时,shareable_mem
被重置为0 - 当然放弃缓存的值。同时,请记住Oracle已为此序列存储LAST_NUMBER
(当我们第一次创建序列时为50)。由于shareable_mem
已刷新且缓存的值已消失,LAST_NUMBER
现已更新为CURRVAL + *CACHE SIZE*
此行为(重置shareable_mem
)也与其他DDL一致。我创建了一个表,注意到V $ _DB_OBJECT_CACHE中的一个条目,其值为shareable_mem
。一旦我执行相同的DDL shareable_mem
值重置为0!