Nye låsefunktioner i dbms_lock: request, release, is_acquired og held_locks

Nye låsefunktioner gør parallelle algoritmer enklere.

PSQL-pakken dbms_lock er blevet udvidet med funktionalitet til navngivet låsning inden for en session: request, release, is_acquired og tabelfunktionen held_locks. Disse låse fungerer udelukkende inden for den egen session; koordinering på tværs af sessioner, processer eller maskiner er uden for rækkevidde.

Funktionalitet

En lås anmodes med dbms_lock.request(navn) og frigives med dbms_lock.release(navn). Navne sammenlignes uden hensyn til store og små bogstaver. En variant med tidsbegrænsning, dbms_lock.request(navn, timeout_sec), accepterer sekunder med decimaler (0.25 er 250 millisekunder) og returnerer undtagelsen lock_timeout ved overskridelse.

En opnået lås gælder for en ikke-parallel udført erklæring, såsom en anonym PSQL-blok eller en blok inden for en parallel. Ikke-frigivne låse giver en fejlagtig besked ved slutningen af erklæringen.

En lås kan opnås flere gange; en tæller stiger derefter. En lås anses for opnået, når tælleren er 1 eller højere, og frigivet når den er 0.

Hvis en dødgang opstår, opstår deadlock_detected.

is_acquired(navn) og held_locks() besvarer udelukkende spørgsmålet for den kaldende ramme.

Eksempel: Anmodning, Tælling og Frigivelse

Det følgende eksempel viser tælleren og tabelfunktionen 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 || ' tæller ' || 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('frigivet');
  end if;
end;

Udgangen lyder:

voorbeeld tæller 2
frigivet

Eksempel: Årsafslutning med Tidsbegrænsning

Det følgende eksempel er direkte eksekverbart og beskytter en finansiel afslutningsproces, der højst må køre én ad gangen pr. administration. Anmodningen venter højst tredive sekunder; hvis afslutningen stadig kører andre steder, rapporterer blokken det og afslutter uden skade:

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('Årets afslutning kører stadig andre steder; denne kørsel springes over.');
      raise;
  end;
  --
  -- Den kritiske sektion: omvurdering og afslutningsposteringer af administrationen.
  --
  update boekjaar_regels@InMemoryStorage
  set    status = 'AFGESLOTEN'
  where  boekjaar = 2026
  ;
  dbms_lock.release('jaarafsluiting-l123456789');
  dbms_output.put_line('Regnskabsår 2026 afsluttet.');
  drop table boekjaar_regels@InMemoryStorage;
end;

Udgangen lyder:

Regnskabsår 2026 afsluttet.

Se også

Tilgængelighed

Den nye funktionalitet er tilgængelig fra release 27.0.