در پایگاه داده اوراکل، transaction به طور سنتی به session وابسته است و زمانی که یک session بسته می شود، transaction مرتبط با آن session هم خاتمه مییابد. از اوراکل 23ai (از 23.6 به بعد)، ویژگی Sessionless Transactions این امکان را فراهم میکند که این وابستگی بین session و transaction از بین برود و تراکنشها این امکان را داشته باشند که به حالت تعلیق درآیند و در session دیگری از سر گرفته شوند.
به عبارتی دیگر، در قابلیت Sessionless Transactions، به هر تراکنش یک شناسه منحصربهفرد اختصاص داده میشود و حتی اگر sessionای که تراکنش را شروع کرده، بسته شود، تراکنش در پایگاه داده باقی میماند و session دیگری میتواند آن را با استفاده از “شناسه منحصربهفرد آن” از سر بگیرد و ادامه دهد.
برای استفاده از این قابلیت، لازم است با تابع DBMS_TRANSACTION.START_TRANSACTION آشنا باشید. این تابع شامل پارامترهای زیر است:
DBMS_TRANSACTION.START_TRANSACTION( xid in raw default null, transaction_type in pls_integer default TRANSACTION_TYPE_LOCAL, timeout in pls_integer default 60, flag in pls_integer default 0 ) RETURN VARCHAR2;
- XID: نام تراکنش.
- TRANSACTION_TYPE: نوع تراکنش، مانند TRANSACTION_TYPE_LOCAL،TRANSACTION_TYPE_SESSIONLESS، یا TRANSACTION_TYPE_XA.
- TIMEOUT: مدت زمانی را که تراکنش میتواند پس از تعلیق دوباره از سر گرفته شود(به ثانیه).
- Flag: این پارامتر میتواند به مقدار TRANSACTION_NEW(برای شروع یک تراکنش جدید) و یا TRANSACTION_RESUME(برای از سرگیری یک تراکنش معلق) تنظیم شود.
در ادامه با ارائه یک سناریو، بیشتر با این قابلیت آشنا خواهیم شد.
مرحله 1: ایجاد یک جدول
اولین قدم، ایجاد یک جدول برای اهداف این سناریو است:
SQL> create table tbl_sessionless (id number,First_name varchar2(20),last_name varchar2(30)); Table created.
مرحله 2: استارت یک Sessionless Transaction
در یک session جدید، یک Sessionless Transaction را استارت می کنیم و در این تراکنش(که arsenal01 نام دارد)، یک رکورد را در جدول فوق درج می کنیم. سپس تراکنش arsenal01 را معلق کرده و جلسه را می بندیم:
–session 1
SQL> select sid from v$mystat where rownum=1;
SID
----------
138
SQL> set serveroutput on
SQL> declare
TRANID VARCHAR2(128);
begin
TRANID := DBMS_TRANSACTION.START_TRANSACTION
( XID => UTL_RAW.CAST_TO_RAW('Arsenal01')
, transaction_type => DBMS_TRANSACTION.TRANSACTION_TYPE_SESSIONLESS
, timeout => 5
, flag => DBMS_TRANSACTION.TRANSACTION_NEW
);
dbms_output.put_line('TRANID is: ' || TRANID);
end;
/
TRANID is: 417273656E616C3031
PL/SQL procedure successfully completed.
SQL> insert into tbl_sessionless values(1,'Vahid','Yousefzadeh');
1 row created.
SQL> select * from tbl_sessionless;
ID FIRST_NAME LAST_NAME
---------- -------------------- ------------------------------
1 Vahid Yousefzadeh
SQL> execute DBMS_TRANSACTION.SUSPEND_TRANSACTION;
PL/SQL procedure successfully completed.
SQL> exit
مرحله 3: از سرگیری(resuming)
Session دیگری شروع کرده و تراکنش arsenal01 را از سر می گیریم:
–session 2:
SQL> select sid from v$mystat where rownum=1;
SID
----------
507
SQL> select * from tbl_sessionless;
no rows selected
SQL> set serveroutput on
SQL> declare
TRANID VARCHAR2(128);
begin
TRANID := DBMS_TRANSACTION.START_TRANSACTION
( xid => UTL_RAW.CAST_TO_RAW('Arsenal01')
, transaction_type => DBMS_TRANSACTION.TRANSACTION_TYPE_SESSIONLESS
, flag => DBMS_TRANSACTION.TRANSACTION_RESUME
);
dbms_output.put_line('Resumed TRANID: '||TRANID);
end;
/
Resumed TRANID: 417273656E616C3031
PL/SQL procedure successfully completed.
SQL> select * from tbl_sessionless;
ID FIRST_NAME LAST_NAME
---------- -------------------- ------------------------------
1 Vahid Yousefzadeh
نتیجه کوئری، رکوردی که درج شده است را برمیگرداند. تراکنش arsenal01 در session جدید فعال است، همانطور که با پرسوجو از v$transaction نشان داده میشود:
SQL> select s.sid,s.TADDR,s.PROGRAM from v$transaction t,v$session s where t.ADDR=s.TADDR;
SID TADDR PROGRAM
---------- ---------------- ------------------------------
507 00000000CB5651E8 sqlplus@OEL9 (TNS V1-V3)
مرحله 4: Commit کردن تراکنش
در نهایت، تراکنش را commit می کنیم تا آن را خاتمه دهیم:
SQL> commit;
Commit complete.
SQL> select * from tbl_sessionless;
ID FIRST_NAME LAST_NAME
---------- -------------------- ------------------------------
1 Vahid Yousefzadeh
پس از commit کردن، تلاش برای از سرگیری تراکنش منجر به خطا خواهد شد:
SQL> set serveroutput on
SQL> declare
TRANID VARCHAR2(128);
begin
TRANID := DBMS_TRANSACTION.START_TRANSACTION
( xid => UTL_RAW.CAST_TO_RAW('Arsenal01')
, transaction_type => DBMS_TRANSACTION.TRANSACTION_TYPE_SESSIONLESS
, flag => DBMS_TRANSACTION.TRANSACTION_RESUME
);
dbms_output.put_line('Resumed TRANID: '||TRANID);
end;
/
ORA-26218: sessionless transaction with GTRID 417273656E616C3031 does not
exist.
ORA-06512: at "SYS.DBMS_TRANSACTION", line 299
ORA-06512: at line 4
Help: https://docs.oracle.com/error-help/db/ora-26218/