در زمان اجرای یک پرس و جوی زمانبر، ممکن است تغییراتی در جداول مرجع این پرس وجو اعمال شود در این صورت، سوالی مطرح می شود که آیا این پرس و جوی در حال اجرا، تغییرات جدید را هم در محاسباتش اعمال می کند یا خیر؟
پاسخ این سوال به نوع جداول و ویوهای مرجع پرس و جو بستگی دارد برای مثال، در زمان رجوع به dynamic performance viewها ممکن است تغییرات ایجاد شده در زمان اجرای پرس و جو لحاظ شود و نهایتا خروجی آن پرس و جو را تغییر دهد.
اما در زمان رجوع به جداولی که اطلاعات کاربران در آن ذخیره می شود، اوراکل با لحاظ کردن scn زمان اجرای پرس و جو(زمانی که پرس و جو شروع به اجرا می کند)، تغییرات جدید را در آن اعمال نخواهد کرد.
در صورتی که تغییرات جدید در محاسبات اعمال نشوند و اوراکل صرفا با کمک تصویر ثابتی که از اطلاعات جدول دارد، پرس و جو را اجرا کند، اصطلاحا مفهوم read consistency توسط اوراکل رعایت شده است.
توجه: مفهوم read consistency ارتباطی به مدت زمان اجرای پرس و جو ندارد و پرس و جوی زمانبر که در مقدمه متن بیان شده، صرفا برای فهم راحت تر مسئله بوده است.
در ادامه متن، با ارائه دو مثال، دو حالت مذکور را توضیح خواهیم داد.
همانطور که بیان شد، در زمان رجوع به dynamic performance viewها، تضمینی برای رعایت read consistency وجود ندارد در مثال زیر این نکته قابل مشاهده می باشد.
SQL> create or replace function stop_func(a number) return number is
2 begin
3 sys.dbms_lock.sleep(a);
4 return a;
5 end;
6 /
Function create
SQL>select a.file#, stop_func(1), (select b.current_scn from v$database b where b.current_scn > a.file#) current_scn from v$datafile a ;
همانطور که می بینید، تغییرات ایجاد شده در مقدار current_scn در خروجی پرس و جو هم اعمال شده و عملا به دلیل استفاده از ویوی v$database در متن پرس و جو، read consistency توسط اوراکل رعایت نشده است.
قصد داریم جدولی را جایگزین ویوی v$database کنیم تا تغییر رفتار اوراکل را در این زمینه مشاهده کنیم.
برای این کار، ابتدا جدولی با نام scn_tbl ایجاد می کنیم که قرار است scn جاری دیتابیس در این جدول هم نگهداری شود:
SQL>create table scn_tbl as select current_scn from v$database;
در قسمت زیر جابی را ایجاد می کنیم تا در هر ثانیه، scn ثبت شده در این جدول را به scn جاری دیتابیس بروزرسانی کند:
begin
sys.dbms_scheduler.create_job(job_name => ‘SYS.MYJOB’,
job_type => ‘PLSQL_BLOCK’,
job_action => ‘begin update scn_tbl set current_scn=(select current_scn from v$database) ; end;’,
start_date => to_date(null),
repeat_interval => ‘Freq=Secondly;Interval=1’,
end_date => to_date(null),
job_class => ‘DEFAULT_JOB_CLASS’,
enabled => true,
auto_drop => false,
comments => ”);
end;
/
اطلاعات جدول scn_tbl توسط جاب ایجاد شده(myjob) ، در حال تغییر می باشد:
SQL> select * from scn_tbl;
CURRENT_SCN
———–
16751463
SQL> /
CURRENT_SCN
———–
16751487
SQL> /
CURRENT_SCN
———–
16751521
با جایگزینی جدول tbl_scn به جای ویوی v$database، خواهیم دید که اوراکل تغییرات را در زمان اجرای پرس و جو نادیده خواهد گرفت.
select a.file#, stop_func(1), (select b.current_scn from scn_tbl b where b.current_scn > a.file#) current_scn from v$datafile a ;
همانطور که می بینید، در این حالت، read consistency توسط اوراکل رعایت شده است.