در پایگاه داده اوراکل، 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/