我想在一個函數內部創建一個事務塊,所以我的目標是在一次使用這個函數,所以如果有人使用這個函數而另一個想使用它,他不能,直到第一個是完成我創建這個功能:PostgreSQL - 開始一個事務塊IN函數
CREATE OR REPLACE FUNCTION my_job(time_to_wait integer) RETURNS INTEGER AS $$
DECLARE
max INT;
BEGIN
BEGIN;
SELECT MAX(max_value) INTO max FROM sch_lock.table_concurente;
INSERT INTO sch_lock.table_concurente(max_value, date_insertion) VALUES(max + 1, now());
-- Sleep a wail
PERFORM pg_sleep(time_to_wait);
RETURN max;
COMMIT;
END;
$$
LANGUAGE plpgsql;
但接縫不工作,我有一個錯誤,語法錯誤BEGIN;
沒有BEGIN;
和COMMIT
我得到一個正確的結果,我用這個查詢來檢查:
-- First user should to wait 10 second
SELECT my_job(10) as max_value;
-- First user should to wait 3 second
SELECT my_job(3) as max_value;
所以結果是:
+-----+----------------------------+------------+
| id | date | max_value |
+-----+----------------------------+------------+
| 1 | 2017-02-13 13:03:58.12+00 | 1 |
+-----|----------------------------+------------+
| 2 | 2017-02-13 13:10:00.291+00 | 2 |
+-----+----------------------------+------------+
| 3 | 2017-02-13 13:10:00.291+00 | 2 |
+-----+----------------------------+------------+
但結果應該是:
+-----+----------------------------+------------+
| id | date | max_value |
+-----+----------------------------+------------+
| 1 | 2017-02-13 13:03:58.12+00 | 1 |
+-----|----------------------------+------------+
| 2 | 2017-02-13 13:10:00.291+00 | 2 |
+-----+----------------------------+------------+
| 3 | 2017-02-13 13:10:00.291+00 | 3 |
+-----+----------------------------+------------+
所以第三個id = 3
應該有max_value = 3
而不是2
,出現這種情況是因爲第一個用戶選擇max = 1並等待10 sec
和第二個用戶選擇max = 1並在插入前等待3 sec
,但正確的解決方案是:我不能使用這個功能,直到第一個完成,因爲我想做一些安全和保護。
我的問題是:
- 我怎樣才能使一個事務塊的一個函數裏?
- 您有什麼建議嗎?我們如何以安全的方式做到這一點?
謝謝。
不幸的是,這是不可能的。函數不能使用提交或回滾。 –
噢,我的上帝,我應該怎麼做@a_horse_with_no_name任何建議? –
你爲什麼不簡單地使用一個序列來生成數字。這將是一個**很快**並且更具可擴展性。 –