Nieuwe vergrendelingsfuncties in dbms_lock: request, release, is_acquired en held_locks

Nieuwe locking-features maken parallelle algoritmes eenvoudiger.

De PSQL-package dbms_lock is uitgebreid met functionaliteit voor named locking binnen een sessie: request, release, is_acquired en de tabelfunctie held_locks. Deze locks werken uitsluitend binnen de eigen sessie; coördinatie over sessies, processen of machines heen valt buiten het bereik.

Werking

Een vergrendeling wordt aangevraagd met dbms_lock.request(naam) en vrijgegeven met dbms_lock.release(naam). Namen worden zonder onderscheid tussen hoofd- en kleine letters vergeleken. Een variant met tijdslimiet, dbms_lock.request(naam, timeout_sec), accepteert seconden met decimalen (0.25 is 250 milliseconden) en geeft bij overschrijding de vangbare exception lock_timeout.

Een verkregen lock geldt voor een niet-parallel uitgevoerd statement, zoals een anoniem PSQL-block of een block binnen een parallel. Niet vrijgegeven locks leiden tot een foutmelding bij einde van het statement.

Een lock kan meerdere keren verkregen worden; een teller loopt dan op. Een lock is verkregen als de teller op 1 of hoger staat, en vrijgegeven als deze 0 is.

Indien een deadlock optreedt, dan treedt deadlock_detected op.

is_acquired(naam) en held_locks() beantwoorden uitsluitend de vraag voor het aanroepende kader.

Voorbeeld: Aanvragen, Tellen en Vrijgeven

Het volgende voorbeeld toont de teller en de tabelfunctie held_locks:

declare
  l_held boolean;
begin
  dbms_lock.request('voorbeeld');
  dbms_lock.request('voorbeeld');
  for r in
  ( select name
    ,      hold_count
    from   table(dbms_lock.held_locks())
  )
  loop
    dbms_output.put_line(r.name || ' teller ' || r.hold_count);
  end loop;
  dbms_lock.release('voorbeeld');
  dbms_lock.release('voorbeeld');
  l_held := dbms_lock.is_acquired('voorbeeld');
  if not l_held
  then
    dbms_output.put_line('vrijgegeven');
  end if;
end;

De uitvoer luidt:

voorbeeld teller 2
vrijgegeven

Voorbeeld: Jaarafsluiting met Tijdslimiet

Het volgende voorbeeld is direct uitvoerbaar en beschermt een financiële afsluitverwerking die per administratie hoogstens één keer tegelijk mag lopen. De aanvraag wacht ten hoogste dertig seconden; loopt de afsluiting elders nog, dan meldt het blok dat en stopt het zonder schade:

begin
  create or replace table boekjaar_regels@InMemoryStorage
  as
  select 2026 boekjaar
  ,      'OPEN' status
  from   dual@DataDictionary
  ;
  begin
    dbms_lock.request('jaarafsluiting-l123456789', 30);
  exception
    when lock_timeout
    then
      dbms_output.put_line('De jaarafsluiting draait elders nog; deze run slaat over.');
      raise;
  end;
  --
  -- De kritieke sectie: herwaardering en afsluitboekingen van de administratie.
  --
  update boekjaar_regels@InMemoryStorage
  set    status = 'AFGESLOTEN'
  where  boekjaar = 2026
  ;
  dbms_lock.release('jaarafsluiting-l123456789');
  dbms_output.put_line('Boekjaar 2026 afgesloten.');
  drop table boekjaar_regels@InMemoryStorage;
end;

De uitvoer luidt:

Boekjaar 2026 afgesloten.

Zie ook

Beschikbaarheid

De nieuwe functionaliteit is beschikbaar vanaf release 27.0.