4

一部の PL/SQL プロシージャは、評価に多くの時間を要します (大量のデータを再計算および更新するため)。

このプロシージャを単一に評価する実行コンテキストの数を制限したい。

別のコンテキストで実行された場合は何もしないでください...

しかし、PL/SQL コードでどのアトミック操作を使用すればよいかわかりません。

:サーバーが手順の評価の途中で停止した場合、テーブル行を同期に使用するとDBの状態が矛盾する可能性があるのではないかと心配しています...

4

1 に答える 1

9

を使用DBMS_LOCK.requestして、一意のロック ハンドルを生成できます。このロックを同時に保持できるセッションは 1 つだけです。セッションのデータベース再起動が予期せず終了した場合、ロックは自動的に解放されます。

ロックがコミット間で保持されるかどうかは、ロックを要求するときに決定します。

次に例を示します。

SQL> CREATE OR REPLACE PROCEDURE serial IS
  2     l_lock_handle  VARCHAR2(128 BYTE);
  3     l_lock_request INTEGER;
  4  BEGIN
  5     dbms_lock.allocate_unique(lockname => 'MY_SERIAL_PROC',
  6                               lockhandle => l_lock_handle);
  7     l_lock_request := dbms_lock.request(lockhandle => l_lock_handle,
  8                                         timeout => 5,
  9                                         release_on_commit => FALSE);
 10     CASE l_lock_request
 11        WHEN 0 THEN
 12           NULL; -- success
 13        WHEN 1 THEN
 14           raise_application_error(-20002, 'lock already reserved');
 15        ELSE
 16           raise_application_error(-20001, 'Lock error: ' || l_lock_request);
 17     END CASE;
 18     BEGIN
 19        ---------- serialized block of code           ----------
 20        ---------- (lock will be kept accross commit) ----------
 21        dbms_lock.sleep(30);
 22        ---------- End of serialized code             ----------
 23     EXCEPTION
 24        WHEN OTHERS THEN -- release lock in case of uncatched error
 25           l_lock_request := dbms_lock.release(lockhandle => l_lock_handle);
 26           RAISE;
 27     END;
 28     l_lock_request := dbms_lock.release(lockhandle => l_lock_handle);
 29  END;
 30  /

Procedure created

同時に 2 つのセッションを実行します。

Session A> exec serial;                

                                       Session B> -- Before session A ends
                                       Session B> exec serial;

                                       ERROR at line 1:
                                       ORA-20002: lock already reserved
                                       ORA-06512: at "APPS.SERIAL", line 13
                                       ORA-06512: at line 1


PL/SQL procedure successfully completed

                                       Session B> -- After session A ends
                                       Session B> exec serial;

                                       PL/SQL procedure successfully completed.
于 2013-06-26T14:05:20.287 に答える