postgresql (perlu) 함수 getTravelTime (integer, timestamp)은 지정된 ID와 타임 스탬프에 대한 데이터를 선택하려고합니다. 데이터가 없거나 데이터가 오래된 경우 외부 서버에서 데이터를 다운로드합니다 (다운로드 시간 ~ 300ms).PostgreSQL에 대한 내 자신의 전역 잠금/잠금 해제 기능을 작성하는 방법
다중 프로세스는이 데이터베이스와이 기능을 사용합니다. 두 프로세스가 데이터를 찾지 못하고 다운로드하여 travel_time 테이블에 삽입하려고하면 오류가 발생합니다 (ID와 타임 스탬프 쌍은 고유해야합니다). 나는 자물쇠에 대해 생각했다. 전체 테이블을 잠그면 모든 프로세스가 차단되어 하나만 진행할 수 있습니다. ID와 타임 스탬프 만 잠글 필요가 있습니다. pg_advisory_lock은 "현재 세션"에서만 잠근 것 같습니다. 하지만 제 프로세스는 자체 세션을 사용합니다.
내 자신의 잠금/잠금 해제 기능을 작성하려고했습니다. 내가 제대로하고 있니? 나는 능동적 인 대기를 사용합니다. 어떻게 이것을 생략 할 수 있습니까? 어쩌면 전역 잠금으로 pg_advisory_lock()을 사용하는 방법이 있을까요?
내 코드 :
CREATE TABLE travel_time_locks (
id_key integer NOT NULL,
time_key timestamp without time zone NOT NULL,
UNIQUE (id_key, time_key)
);
------------
-- Function: mylock(integer, timestamp)
DROP FUNCTION IF EXISTS mylock(integer, timestamp) CASCADE;
-- Usage: SELECT mylock(1, '2010-03-28T19:45');
-- function tries to do a global lock similar to pg_advisory_lock(key, key)
CREATE OR REPLACE FUNCTION mylock(id_input integer, time_input timestamp)
RETURNS void AS
$BODY$
DECLARE
rows int;
BEGIN
LOOP
BEGIN
-- active waiting here !!!! :(
INSERT INTO travel_time_locks (id_key, time_key) VALUES (id_input, time_input);
EXCEPTION WHEN unique_violation THEN
CONTINUE;
END;
EXIT;
END LOOP;
END;
$BODY$ LANGUAGE 'plpgsql' VOLATILE
COST 1;
------------
-- Function: myunlock(integer, timestamp)
DROP FUNCTION IF EXISTS myunlock(integer, timestamp) CASCADE;
-- Usage: SELECT myunlock(1, '2010-03-28T19:45');
-- function tries to do a global unlock similar to pg_advisory_unlock(key, key)
CREATE OR REPLACE FUNCTION myunlock(id_input integer, time_input timestamp)
RETURNS integer AS
$BODY$
DECLARE
BEGIN
DELETE FROM ONLY travel_time_locks WHERE id_key=id_input AND time_key=time_input;
RETURN 1;
END;
$BODY$ LANGUAGE 'plpgsql' VOLATILE
COST 1;
phppgadmin에서 수행 할 수있는 작업은 다음과 같습니다. SELECT pg_advisory_lock (5); SELECT pg_advisory_lock (5); SELECT 5; 두 번째 쿼리에서 차단 될 것으로 예상되지만 ... 대신 1ms 이상 지나면 "5"가됩니다 ... 왜요? – rafalmag
확인. 이제 그 이유를 알았어. phpPgAdmin의 SQL 창이 트랜잭션이 아닙니다. 자물쇠는 아무 것도 사용하지 않을 때 자동으로 열립니다. 힌트 : 'psql'의 테스트 잠금 성능 향상 – rafalmag