sql >> データベース >  >> RDS >> Oracle

PL/SQLプロシージャの同期。一度に1つだけ手順の実行を保証するにはどうすればよいですか?

    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.
    



    1. 時間差を見つけるためのSQL計算

    2. Dockerを介してローカルホスト上のMySQLサーバーに接続する

    3. MySQLクエリ-最新バージョンのエントリのみを使用した内部結合

    4. 関連性によるMySQLの順序