Я пытаюсь использовать создание транзакционного блока внутри функции, поэтому моя цель - использовать эту функцию по одному, поэтому, если кто-то использует эту функцию, а другой хочет ее использовать он не может, пока первый один не конец я создаю эту функцию:PostgreSQL - Запуск A Блок транзакций 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 какое-нибудь предложение? –
Почему бы вам просто не использовать последовательность для генерации чисел. Это будет ** много ** быстрее и гораздо более масштабируемым. –