2011-05-26 75 views
0

我目前使用的是Postgres 8.3。我創建了一個表,充當另一個表中存在的成員的髒標誌表。我在成員表上插入或更新後應用了觸發器,這些成員表將在修改表中插入/更新值爲true的記錄。觸發器似乎工作,但我注意到有東西是翻轉布爾is_modified值。我不知道如何去嘗試隔離可能會翻轉它的東西。奇怪的行爲

觸發功能:

BEGIN; 
    CREATE OR REPLACE FUNCTION set_member_as_modified() RETURNS TRIGGER AS $set_member_as_modified$ 
    BEGIN 
LOOP 
    -- first try to update the key 
    UPDATE member_modification SET is_modified = TRUE, updated = current_timestamp WHERE "memberID" = NEW."memberID"; 
    IF FOUND THEN 
    RETURN NEW; 
    END IF; 
    --member doesn't exist in modification table, so insert them 
    -- if someone else inserts the same key conncurrently, raise a unique-key failure 
    BEGIN 
    INSERT INTO member_modification("memberID",is_modified,updated) VALUES(NEW."memberID", TRUE,current_timestamp); 
    RETURN NEW; 
    EXCEPTION WHEN unique_violation THEN 
    -- do nothing, and loop to try the update again 
    END; 
END LOOP; 
    END; 
$set_member_as_modified$ LANGUAGE plpgsql; 
COMMIT; 

CREATE TRIGGER set_member_as_modified AFTER INSERT OR UPDATE ON members FOR EACH ROW EXECUTE PROCEDURE set_member_as_modified(); 

這裏是我運行SQL和結果:

 $CREATE TRIGGER set_member_as_modified AFTER INSERT OR UPDATE ON members FOR EACH ROW EXECUTE PROCEDURE set_member_as_modified(); 

結果:

 UPDATE 1 
    bluesky=# select * from member_modification; 
    -[ RECORD 1 ]---+--------------------------- 
modification_id | 14 
is_modified  | t 
updated   | 2011-05-26 09:49:47.992241 
memberID  | 182346 

bluesky=# select * from member_modification; 
-[ RECORD 1 ]---+--------------------------- 
modification_id | 14 
is_modified  | f 
updated   | 2011-05-26 09:49:47.992241 
memberID  | 182346 

正如你所看到的東西翻轉is_modified值。 postgres中有什麼我可以用來確定什麼查詢/進程正在這個表上的行爲?

回答

1

你確定你已經發布所需要的一切? member_modification上的兩個查詢表明正在運行一個單獨的查詢,該查詢將is_modified設置回false。

你可以一個text[]字段添加到member_modification,例如query_trace text[] not null default '{}',然後和之前在該表的每一行插入/更新觸發器肚裏是這樣的:

NEW.query_trace := NEW.query_trace || current_query(); 

如果current_query()是不是在8.3可用,看到這一點:

http://www.postgresql.org/docs/8.3/static/monitoring-stats.html

SELECT pg_stat_get_backend_pid(s.backendid) AS procpid, 
     pg_stat_get_backend_activity(s.backendid) AS current_query 
    FROM (SELECT pg_stat_get_backend_idset() AS backendid) AS s; 

然後,您可以讓受影響的後續查詢列表:

select query_trace[i] from generate_series(1, array_length(query_trace, 1)) as i