sql >> Databasteknik >  >> RDS >> Oracle

Synkronisering av PL/SQL-proceduren. Hur garanterar man att förfarandet utförs endast en åt gången?

Du kan använda DBMS_LOCK.request för att skapa ett unikt låshandtag. Endast en session kan hålla detta lås samtidigt. Om databasen startar om sessionen oväntat slutar, släpps låset automatiskt.

Du bestämmer när du begär låset om låset ska hållas över commits eller inte.

Här är ett exempel:

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

Jag kör två sessioner samtidigt:

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. Anslutning Java - MySQL:Hämtning av offentlig nyckel är inte tillåten

  2. Returnera antalet rader som påverkas av UPDATE-satser

  3. att skapa pg_cron-tillägg inom docker-entrypoint-initdb.d misslyckas

  4. Flera frågedata i en enda HTML-tabell (PHP, Mysql) array skrivs inte ut i rätt position?