sql >> Databasteknik >  >> RDS >> PostgreSQL

Timeout för rådgivande lås i postgresql

Detta är en prototyp av ett omslag som dåligt emulerar DBMS_LOCK.REQUEST - begränsad till endast en typ av lås (rådgivningslås för transaktionsomfång).

För att göra funktionen fullt kompatibel med Oracles skulle det behövas flera hundra rader. Men det är en början.

CREATE OR REPLACE FUNCTION
advisory_xact_lock_request(p_key bigint, p_timeout numeric)
RETURNS integer
LANGUAGE plpgsql AS $$
/*  Imitate DBMS_LOCK.REQUEST for PostgreSQL advisory lock. 
Return 0 on Success, 1 on Timeout, 3 on Parameter Error. */
DECLARE
    t0 timestamptz := clock_timestamp();
BEGIN
    IF p_timeout NOT BETWEEN 0 AND 86400 THEN
        RAISE WARNING 'Invalid timeout parameter';
        RETURN 3;
    END IF;
    LOOP
        IF pg_try_advisory_xact_lock(key) THEN
            RETURN 0;
        ELSIF clock_timestamp() > t0 + (p_timeout||' seconds')::interval THEN
            RAISE WARNING 'Could not acquire lock in % seconds', p_timeout;
            RETURN 1;
        ELSE
            PERFORM pg_sleep(0.01); /* 10 ms */
        END IF;
    END LOOP;
END;
$$;

Testa det med den här koden:

SELECT CASE 
    WHEN advisory_xact_lock_request(1, 2.5) = 0
    THEN pg_sleep(120)
END; -- and repeat this in parallel session 

/* Usage in Pl/PgSQL */

lkstat := advisory_xact_lock_request(lkhndl, lktimeout);



  1. SKAPA SCHEMA OM INTE FINNS ger upphov till dubblettnyckelfel

  2. Hur definierar man en unik begränsning på en kolumn i MySQL-tabellen i Ruby on Rails 3?

  3. WAMP Kan inte komma åt på det lokala nätverket 403 Förbjudet

  4. Garanterar UNION ALL ordningen på resultatuppsättningen