假設我有一個message
關係,我保存已被該命令創建的消息:SELECT INTO與SELECT在PostgreSQL中
CREATE TABLE message
(
id serial primary key,
foo1 integer,
foo2 integer,
foo3 text
)
而且我們有得到了消息,並從關係中刪除的功能,像這樣:
CREATE FUNCTION get_and_delete_message(p_foo1 integer)
RETURNS TABLE(r_id integer, r_foo1 integer, r_foo2 integer, r_foo3 text) AS $$
DECLARE
message_id integer;
BEGIN
SELECT id INTO message_id FROM message WHERE foo1 = p_foo1 LIMIT 1;
RETURN QUERY SELECT * FROM message WHERE foo1 = p_foo1 LIMIT 1;
DELETE FROM message where id = message_id;
END;
$$ LANGUAGE plpgsql;
假設READ_COMMITTED
隔離級別,它可能是從兩個用戶兩個併發事務返回相同的消息,但顯然僅有的刪除/獲取它。這不是我的應用程序所需的行爲,我希望只有一個用戶閱讀一條消息。
假設REPEATABLE_READ
這不會發生。
但閱讀FOR UPDATE
後,我想也許它仍然可以使用READ_COMMITTED
水平和改變get_and_delete_message
功能如下:
...
BEGIN
SELECT id INTO message_id FROM message WHERE foo1 = p_foo1 LIMIT 1;
RETURN QUERY SELECT * FROM message WHERE foo1 = p_foo1 LIMIT 1 FOR UPDATE;
DELETE FROM message where id = message_id;
END;
...
從我的理解,在第二SELECT
使用FOR UPDATE
實際上將鎖定返回的行直到事務結束,所以如果我們有兩個併發事務,則只有一個事實上會返回並刪除該消息。
這是這種情況?或者我也應該做SELECT id INTO message_id FROM message WHERE foo1 = p_foo1 LIMIT 1 FOR UPDATE
?我找不到有關SELECT INTO
與FOR UPDATE
相結合的任何信息。有關於此的任何想法?
這是在'READ_COMMITTED'隔離級別去保證我沒有2個併發事務返回相同的消息嗎?更多的東西:其實我試圖讓我的問題的例子簡單,所以我有'SELECT ... ORDER BY',似乎不可能用'DELETE'做同樣的事情。 最後,你的回答並沒有真正回答我的問題:S,儘管我很欣賞你回答的時間 – insumity 2014-10-04 23:52:20