※ 本記事は、Ulrike Schwinnによる”Automatic transaction rollback in 23c with high, medium and low priority transactions“を翻訳したものです。

2023年5月17日


自動トランザクション・ロールバックは、23cのもう1つの非常に興味深い新しいトピックです。行ロックを保持しているトランザクションを、そのセッションを終了することによって自動的にロールバックできるタイミングを制御する機能を提供します。

たとえば、あるアプリケーションが長時間一部の行を変更し、Oracleが、ある種のDML操作などによって変更される各行の行ロックを取得したとします。ロックされたrows.Toによってロックされた行が解放されないかぎり、行ロック上の別のトランザクションをブロックできます。COMMITまたはROLLBACKは、ロックを保持しているセッションで発行する必要があります。ALTER SYSTEM KILLでセッションを強制終了してブロックしているトランザクションを手動で終了するか、ALTER SYSTEM CANCEL SQLでSQL文を取り消す必要がある場合があります。

この機能を実装するには、決定が必要で、その場合はトランザクションがロールバックされます。したがって、トランザクションには異なる優先順位が導入されています。つまり、トランザクションの優先度を定義できるようになりました。低、中および高(デフォルト)を選択できます。自動トランザクション・ロールバック機能では、優先度の低いトランザクションが自動的にロールバックされ、優先度の高いトランザクションが事前定義された待機時間の後に行ロックの取得をブロックされます。トランザクションのデフォルトの優先度は常に高く、自動ロールバックは有効になっていません。

この機能を実装するには、トランザクション優先度と待機時間の両方のパラメータを設定する必要があります。次に、2つのパラメータの簡単な定義を示します。パラメータの詳細は、データベース・リファレンスを参照してください。

  • 待機パラメータは2つ: TXN_AUTO_ROLLBACK_HIGH_PRIORITY_WAIT_TARGETとTXN_AUTO_ROLLBACK_MEDIUM_PRIORITY_WAIT_TARGETがあります。両方が最大期間を秒単位で制御します。優先度を持つトランザクション
    HIGHおよびMEDIUMは、この定義された待機時間を待ってから、データベースで行ロックを保持するより低い優先度のトランザクションをロールバックします。デフォルト値は2147483647です。
    ノート: このパラメータを構成するには、ALTER SYSTEM権限が必要です。たとえば、PDBレベルまたはCDBレベルで次のALTER SYSTEMコマンドを使用して、待機パラメータを10秒に設定します。
    SQL> alter system set txn_auto_rollback_high_priority_wait_target = 20;
  • トランザクション優先度パラメータはTXN_PRIORITYで、値はLOW、MEDIUMおよびHIGHです。ALTER SESSIONコマンドで定義できます。次のALTER SESSIONコマンドを使用して、値をLOWに設定します。
    SQL> alter session set txn_priority = low;

ノート: すべてのトランザクションはデフォルトの優先度HIGHです。

次に、3つのトランザクション(2つの低トランザクションと1つの高トランザクション)がある単純なシナリオで機能について説明します。3つとも、表のmycheckの値を変更します。

これがこの例で使用する表です。

SQL> select * from mycheck;
VALUE
----------        
          1

上位トランザクションのパラメータ設定を確認します。大きいトランザクションの待機パラメータは、ALTER SYSTEMコマンド(前述を参照)で20に設定されています。

SQL> col name format a50 
SQL> col value format a10 
SQL> select name, value from v$parameter where name like 'tx%';
VALUE
-------------------------------------------------- ----------
txn_priority                                       HIGH 
txn_auto_rollback_high_priority_wait_target        20 
txn_auto_rollback_medium_priority_wait_target      2147483647 
txn_auto_rollback_mode                             ROLLBACK

ノート: 新しいロールDB_DEVELOPER_ROLEを持つ開発者として、V$PARAMETERもチェックできるようになりました。

この表はシナリオを示しています。

Time Transaction1 Low Transaction2 Low Transaction3 High (Default)
t1 alter session set txn_priority = low;
select sys_context('userenv','SID');
SYS_CONTEXT('USERENV','SID')
-----------------------------
277


update scott.mycheck set value=0;
1 rows updated.

 

 
t2  

alter session set txn_priority = low;
SQL> select sys_context('userenv','SID');
SYS_CONTEXT('USERENV','SID')
-----------------------------
43

update scott.mycheck set value=10;
-- is waiting

 
t3     SQL> select sys_context('userenv','SID'); SYS_CONTEXT('USERENV','SID')
----------------------------
32

update scott.
mycheck set value=1000;
-- maximum wait time 20 seconds
t3 to t4
(<=t3+20) 
    1 rows updated.
t5  SQL> select sysdate;
select sysdate
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel
Process ID: 33042
Session ID: 274 Serial number: 59494
SQL> select sysdate;
select sysdate
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel
Process ID: 33050
Session ID: 272 Serial number: 64477
SQL> select * from scott.mycheck;

     VALUE
----------
      1000

ノート: ブロッカ・トランザクション(ここでは277と43)は、対応するセッション・トランザクションを終了することでロールバックされます。

これをどのように監視できますか?
V$SESSIONまたはV$TRANSACTION(あるいはその両方)を使用します。EVENT、SECONDS_IN_WAITおよびBLOCKING_SESSION列を含むV$SESSIONは、ロック状況の分析に役立ちます。新しい列TXN_PRIORITYおよびTXN_PRIORITY_WAIT_TARGETを含むV$TRANSACTIONは、行ロックを保持しているトランザクションとその優先度について通知します。別のセッションですでに保持されている行レベル・ロックを待機しているセッションに関する情報を取得するには、「enq: TX」でフィルタします。

t1からt5までの間に何が起こりましたか?
t1で、ユーザーは優先度の低いトランザクションでUPDATEを発行します。前述のv$ビューを問い合せると、結果が次のようになります。

SQL> select sid, event, seconds_in_wait, blocking_session
     from v$session where  event like '%enq%';

no rows selected.
SQL> select txn_priority, txn_priority_wait_target from v$transaction;

TXN_PRI TXN_PRIORITY_WAIT_TARGET
------- ------------------------
LOW                            0

t2では、同じ表のUPDATEが、別のセッションから優先度の低いトランザクション(SID 277)で発行されます。V$SESSIONに行ロックおよびブロックしているセッション(SID 43)が表示されます。

SQL> select SID, EVENT, SECONDS_IN_WAIT, BLOCKING_SESSION 
     from v$session where  event like '%enq%';

SID                                     EVENT  SECONDS_IN_WAIT BLOCKING_SESSION
---------- ----------------------------------- --------------- ----------------
       277 enq: TX - row lock (LOW priority)                 7               43

SQL> select txn_priority, txn_priority_wait_target from v$transaction;

TXN_PRI TXN_PRIORITY_WAIT_TARGET
------- ------------------------
LOW                            0

t3では、優先度の高いトランザクション(SID 32)の更新が発生します。V$SESSIONに2つのエントリがあり、2つのセッションが待機しています。

SQL> select sid, event, seconds_in_wait, blocking_session      
     from v$session where  event like '%enq%';

 SID       EVENT                               SECONDS_IN_WAIT BLOCKING_SESSION
---------- ----------------------------------- --------------- ----------------
        32 enq: TX - row lock (HIGH priority)                3               43
       277 enq: TX - row lock (LOW priority)                72               43


t3からt4 (t4 <= t3+20秒)の間では、待機値の秒が増加します。

SQL> select sid, event, seconds_in_wait, blocking_session 
     from v$session where  event like '%enq%';

 SID       EVENT                               SECONDS_IN_WAIT BLOCKING_SESSION
---------- ----------------------------------- --------------- ----------------
        32 enq: TX - row lock (HIGH priority)               11               43
       277 enq: TX - row lock (LOW priority)                80               43
SQL> select sid, event, seconds_in_wait, blocking_session 
     from v$session where  event like '%enq%';

SID        EVENT                               SECONDS_IN_WAIT BLOCKING_SESSION
---------- ----------------------------------- --------------- ----------------
        32 enq: TX - row lock (HIGH priority)               17               43
       277 enq: TX - row lock (LOW priority)                86               43

最大待機時間(TXN_AUTO_ROLLBACK_HIGH_PRIORITY_WAIT_TARGET)に達すると、行のロックが解除され、優先度の高いトランザクションで行が更新されます。

SQL> select sid, event, seconds_in_wait, blocking_session
     from v$session where  event like '%enq%';

SID        EVENT                               SECONDS_IN_WAIT BLOCKING_SESSION
---------- ----------------------------------- --------------- ----------------
        32 enq: TX - row lock (HIGH priority)               19              277

t5の後、行ロックがなくなり、2つの優先度の低いセッションが終了します。

SQL> select sid, event, seconds_in_wait, blocking_session 
     from v$session where event like '%enq%';
no rows selected
SQL> select txn_priority, txn_priority_wait_target from v$transaction;

TXN_PRI TXN_PRIORITY_WAIT_TARGET
------- ------------------------
HIGH                          20

アラート・ファイルを確認すると、次のエントリが表示される場合があります。トランザクションが終了するたびに、エントリを受け取ります。この場合、セッションID 43および277のトランザクションが影響を受けます。

FREEPDB1(3):Session (sid: 43, serial: 23355, xid: 4.1.8913, txn_priority: "LOW") terminated by transaction (sid: 32, serial: 11674, xid: -1.-1.-1, txn_priority: "HIGH") because of the parameter "txn_auto_rollback_high_priority_wait_target = 20"

2023-05-09T11:31:01.437420+00:00
FREEPDB1(3):Session (sid: 277, serial: 48468, xid: 1.32.8943, txn_priority: "LOW") terminated by transaction (sid: 32, serial: 11674, xid: -1.-1.-1, txn_priority: "HIGH") because of the parameter "txn_auto_rollback_high_priority_wait_target = 20"  

まとめ
自動トランザクション・ロールバック機能を使用するには、2つのタイプのパラメータ(待機時間(中または低)と、優先順位を付けるセッションの1つ)のみを設定する必要があります。デフォルトの優先度は高いため、自動的にロールバックされません。待機および優先度のパラメータを設定しない場合、自動トランザクション・ロールバックは行われません。

V$SESSIONまたはV$TRANSACTIONの動作をモニターできます。トランザクションが終了するたびに、アラート・ログにもアラートが表示されます。
 
オプションで、パラメータTXN_AUTO_ROLLBACK_MODEを設定できます。これには、ROLLBACK (デフォルト)とTRACKの2つの値があります(機能を試す場合のみ)。最後のケースでは、データベースはV$SYSSTATの統計のみを増分します。詳細は、データベース管理者ガイドも確認してください。