در دیتابیس اوراکل، state بسته‌های PL/SQL در سطح session حفظ می شود. یعنی زمانی که یک package در session ای اجرا می‌شود، متغیرهای global آن، مقادیر خود را در میان چندین فراخوانی حفظ می‌کنند. در نسخه‌های قبلی Oracle(قبل از 26ai)، زمانی که یک package دوباره compile می‌شد، تمام sessionهایی که state آن package را نگه داشته اند با خطاهای ORA-04068 مواجه می‌شدند.

در اوراکل 26ai، عبارت RESETTABLE راهی جدید برای مدیریت state بسته‌های PL/SQL معرفی می‌کند. با استفاده از این عبارت، زمانی که package تشخیص دهد وضعیت آن دیگر معتبر نیست، به‌صورت خودکار reset می‌شود، و مانع از کرش کردن session می شود. برای درک بهتر عملکرد آن، سناریوی عملی زیر را بررسی می‌کنیم. 

1.رفتار پیش‌فرض package (بدون استفاده از RESETTABLE)

ابتدا یک package ساده همراه با یک متغیر global و یک procedure که مقدار متغیر را در هر اجرا یک عدد افزایش می دهد را ایجاد می‌کنیم.

CREATE OR REPLACE PACKAGE my_pkg AS Glob_cnt number := 0; PROCEDURE prc_inc_cnt;
END my_pkg;
/
Package created
CREATE OR REPLACE PACKAGE BODY my_pkg AS PROCEDURE prc_inc_cnt IS BEGIN Glob_cnt := Glob_cnt + 1; DBMS_OUTPUT.PUT_LINE('Counter = ' || Glob_cnt); END;
END my_pkg;
/
Package body created

اکنون رفتار آن را در دو session مختلف بررسی می‌کنیم.

SQL> set serveroutput on
SQL> exec my_pkg.prc_inc_cnt;
Counter = 1
SQL> exec my_pkg.prc_inc_cnt;
Counter = 2

Session 2:

SQL> alter package my_pkg compile;
Package altered
SQL> exec my_pkg.prc_inc_cnt;
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package "VAHID.MY_PKG" has been invalidated
ORA-04065: not executed, altered or dropped package "VAHID.MY_PKG"
ORA-06508: PL/SQL: could not find program unit being called: "VAHID.MY_PKG"
ORA-06512: at line 1

در اینجا، session با خطا مواجه می‌شود زیرا دیتابیس به هنگام recompile شدن package در session 2، وضعیت آن را در session 1 حذف می‌کند. فراخوانی بعدی باعث می‌شود package دوباره مقداردهی اولیه شود:

SQL> set serveroutput on
SQL> exec my_pkg.prc_inc_cnt;
Counter = 1
SQL> exec my_pkg.prc_inc_cnt;
Counter = 2

2. استفاده از عبارت RESETTABLE

حال package را تغییر می‌دهیم تا از عبارت RESETTABLE استفاده کنیم. این عبارت باید مستقیماً در دستور CREATE PACKAGE استفاده شود:

CREATE OR REPLACE PACKAGE my_pkg RESETTABLE AS Glob_cnt number := 0; PROCEDURE prc_inc_cnt;
END my_pkg;
/
Package created
CREATE OR REPLACE PACKAGE BODY my_pkg RESETTABLE AS PROCEDURE prc_inc_cnt IS BEGIN Glob_cnt := Glob_cnt + 1; DBMS_OUTPUT.PUT_LINE('Counter = ' || Glob_cnt); END;
END my_pkg;
/
Package body created

در ادامه همان سناریو را تکرار می‌کنیم تا ببینیم رفتار package با استفاده از RESETTABLE چگونه متفاوت است.

SQL> set serveroutput on
SQL> exec my_pkg.prc_inc_cnt;
Counter = 1
SQL> exec my_pkg.prc_inc_cnt;
Counter = 2

Session 2: 

SQL> ALTER PACKAGE my_pkg COMPILE;
Package altered
SQL> exec my_pkg.prc_inc_cnt;
Counter = 1
SQL> exec my_pkg.prc_inc_cnt;
Counter = 2

در این حالت دیگر خطای ORA-04068 مشاهده نمی‌شود و مقدار متغیر به‌ صورت خودکار reset شده است. 

Vahid Yousefzadeh

ارائه خدمات مشاوره ، پشتیبانی و نصب و راه اندازی پایگاه داده اوراکل در سراسر کشور...................... تلفن: 09128110897 ایمیل:[email protected]

دیدگاهتان را بنویسید لغو پاسخ