カーソルによる読み取り一貫性確認

(8.0.22)

drop table tab1;
create table tab1(col1 int primary key);
insert into tab1 values(1);
insert into tab1 values(2);
select * from tab1;


drop procedure proc1;

delimiter //
create procedure proc1()
begin
declare done int default 0;
declare c1 int;
declare cur1 cursor for select col1 from tab1;
declare continue handler for not found set done = 1;
open cur1;
select current_timestamp;
do sleep(20);
select current_timestamp;
a_loop: loop
fetch cur1 into c1;
if done = 1 then
leave a_loop;
end if;
select c1;
end loop;
close cur1;
end
//
delimiter ;

call proc1();

-- カーソルオープン後スリープ中に別セッションからデータ削除実行
select * from tab1;
delete from tab1;
select * from tab1;

→削除されたデータも表示され、読み取り一貫性あり

 

(19c)

drop table tab1 purge;
create table tab1(col1 int primary key);
insert into tab1 values(1);
insert into tab1 values(2);
commit;
select * from tab1;


set serveroutput on size 20000
declare
cursor cur1 is select col1 from tab1;
c1 cur1%rowtype;
v_now varchar2(100);
begin
open cur1;
select to_char(sysdate,'yyyy/mm/dd hh24:mi:ss') into v_now from dual;
dbms_output.put_line(v_now);
dbms_lock.sleep(20);
select to_char(sysdate,'yyyy/mm/dd hh24:mi:ss') into v_now from dual;
dbms_output.put_line(v_now);
loop
fetch cur1 into c1;
exit when cur1%notfound;
dbms_output.put_line(c1.col1);
end loop;
close cur1;
end;
/


-- カーソルオープン後スリープ中に別セッションからデータ削除実行
select * from tab1;
delete from tab1;
commit;
select * from tab1;


→削除されたデータも表示され、読み取り一貫性あり

 

(13)

drop table tab1;
create table tab1(col1 int primary key);
insert into tab1 values(1);
insert into tab1 values(2);
select * from tab1;


do $$
declare
cur1 cursor for select col1 from tab1;
c1 record;
v_now varchar(100);
begin
open cur1;
select clock_timestamp()::varchar into v_now;
raise notice '%',v_now;
perform pg_sleep(20);
select clock_timestamp()::varchar into v_now;
raise notice '%',v_now;
loop
fetch cur1 into c1;
if not found then
exit;
end if;
raise notice '%',c1.col1;
end loop;
close cur1;
end
$$
;


-- カーソルオープン後スリープ中に別セッションからデータ削除実行
select * from tab1;
delete from tab1;
select * from tab1;


→削除されたデータも表示され、読み取り一貫性あり

(2019)

drop table tab1;
create table tab1(col1 int primary key);
insert into tab1 values(1);
insert into tab1 values(2);
select * from tab1;


declare @col1 int;
declare cur1 INSENSITIVE cursor for select col1 from tab1;
open cur1;
print sysdatetime();
waitfor delay '00:00:20';
print sysdatetime();
fetch next from cur1 into @col1;
while (@@fetch_status = 0)
begin
print @col1;
fetch next from cur1 into @col1;
end
close cur1;
deallocate cur1;

 

-- カーソルオープン後スリープ中に別セッションからデータ削除実行
select * from tab1;
delete from tab1;
select * from tab1;


→削除されたデータも表示され、読み取り一貫性あり

※カーソルオープン後、カーソル内容を固定するためにはINSENSITIVEを指定必要