Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / PostgreSQL Новый топик    Ответить
 Добавление 2х одинаковых записей в таблицу  [new]
a.klevtsov
Member

Откуда:
Сообщений: 4
Добрый день! У нас периодически создаётся 2 одинаковые записи в таблице с разницей во времени примерно .0002 сек. Возможно приходит 2 запроса, но отловить не можем. Хотим решить это на уровне БД.
Как правильно сделать блокировку? Чтобы добавлялась только одна запись

-- Функция предназначена для того, чтобы некие повторяющиейся и паралельные действия блокировать
CREATE OR REPLACE FUNCTION dbo.fn_lock_various_datum_block(
_accid integer,
_name text,
_value text,
_value_if_null text)
RETURNS text
LANGUAGE 'sql'
COST 100
VOLATILE PARALLEL UNSAFE
AS $BODY$

WITH sel AS (
SELECT data
FROM variousdata
WHERE name = _name
LIMIT 1
),
upd AS (
UPDATE variousdata
SET data = _value
WHERE name = _name AND EXISTS(SELECT * FROM sel)
RETURNING data
),
ins AS (
INSERT INTO variousdata(data, name, accountid)
SELECT _value, _name, _accid
WHERE NOT EXISTS(SELECT * FROM sel)
RETURNING data
)
SELECT COALESCE(sel.data, _value_if_null)
FROM (SELECT 0) z
FULL JOIN sel ON (true)
FULL JOIN ins ON (true)
LIMIT 1;
$BODY$;
11 июн 21, 06:25    [22334155]     Ответить | Цитировать Сообщить модератору
 Re: Добавление 2х одинаковых записей в таблицу  [new]
court
Member

Откуда:
Сообщений: 2335
a.klevtsov
Хотим решить это на уровне БД.
уникальный INDEX / KEY сделай на те поля, которые характеризуют "одинаковость" записей
11 июн 21, 06:49    [22334156]     Ответить | Цитировать Сообщить модератору
 Re: Добавление 2х одинаковых записей в таблицу  [new]
a.klevtsov
Member

Откуда:
Сообщений: 4
Он есть, по orderId. Но по остальным полям данные могут совпадать, нужно как то ограничить, что в одну секунду не могут 2 одинаковых записи создаться
11 июн 21, 08:36    [22334168]     Ответить | Цитировать Сообщить модератору
 Re: Добавление 2х одинаковых записей в таблицу  [new]
court
Member

Откуда:
Сообщений: 2335
a.klevtsov
Он есть, по orderId.

court
уникальный INDEX / KEY сделай на те поля, которые характеризуют "одинаковость" записей
11 июн 21, 10:22    [22334201]     Ответить | Цитировать Сообщить модератору
 Re: Добавление 2х одинаковых записей в таблицу  [new]
a.klevtsov
Member

Откуда:
Сообщений: 4
Вы видимо не так поняли или я не так объяснил.
От клиента приходит сразу 2 запроса одинаковых (причина пока неизвестна) с разницей во времени менее 1 сек и соответственно создаётся 2 заказа, но должен быть только один.
Все поля могут быть одинаковые, кроме orderId и даты создания, но когда создаётся 2 заказа, дата создания отличается менее чем на 1 секунду. Почему вообще может приходить 2 запроса и как можно решить проблему?
14 июн 21, 07:50    [22334933]     Ответить | Цитировать Сообщить модератору
 Re: Добавление 2х одинаковых записей в таблицу  [new]
Ivan Durak
Member

Откуда: Minsk!!!
Сообщений: 3715
a.klevtsov
Вы видимо не так поняли или я не так объяснил.
От клиента приходит сразу 2 запроса одинаковых (причина пока неизвестна) с разницей во времени менее 1 сек и соответственно создаётся 2 заказа, но должен быть только один.
Все поля могут быть одинаковые, кроме orderId и даты создания, но когда создаётся 2 заказа, дата создания отличается менее чем на 1 секунду. Почему вообще может приходить 2 запроса и как можно решить проблему?

создай доп колонку по дате с округлением по секунду и на нее+все поля уникальный индекс.

А проблемы в клиенте где-то понятно
14 июн 21, 10:03    [22334955]     Ответить | Цитировать Сообщить модератору
 Re: Добавление 2х одинаковых записей в таблицу  [new]
a.klevtsov
Member

Откуда:
Сообщений: 4
А если 1 заказ в 1.999 сек. создастся, а второй в 2.001 и округление по секунде уже не сработает
14 июн 21, 12:05    [22334995]     Ответить | Цитировать Сообщить модератору
 Re: Добавление 2х одинаковых записей в таблицу  [new]
Ivan Durak
Member

Откуда: Minsk!!!
Сообщений: 3715
a.klevtsov
А если 1 заказ в 1.999 сек. создастся, а второй в 2.001 и округление по секунде уже не сработает

а если бы он вез патроны?
14 июн 21, 13:10    [22335007]     Ответить | Цитировать Сообщить модератору
 Re: Добавление 2х одинаковых записей в таблицу  [new]
KATEROK
Member

Откуда:
Сообщений: 22
А если создать триггер на вставку строк?
Что-то типо такого:

CREATE FUNCTION ins_check() RETURNS trigger AS $ins_check$
    BEGIN
        IF NEW.order_time - (SELECT MAX(order_time)
            FROM orders
            WHERE customer = NEW.customer) < interval '00:00:02' THEN
            RAISE EXCEPTION 'double inserting';
        END IF;
        RETURN NEW;
    END;
$ins_check$ LANGUAGE plpgsql;

CREATE TRIGGER ins_check BEFORE INSERTE ON orders
    FOR EACH ROW EXECUTE FUNCTION ins_check();
14 июн 21, 16:46    [22335094]     Ответить | Цитировать Сообщить модератору
 Re: Добавление 2х одинаковых записей в таблицу  [new]
Maxim Boguk
Member

Откуда: Melbourne, Австралия
Сообщений: 4785
KATEROK,

Не поможет... первая запись может еще не быть закомиченной и соответвенно не видимой триггеру на вторую вставку.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
14 июн 21, 17:02    [22335103]     Ответить | Цитировать Сообщить модератору
 Re: Добавление 2х одинаковых записей в таблицу  [new]
Кесарь
Member

Откуда:
Сообщений: 653
a.klevtsov
Вы видимо не так поняли или я не так объяснил.
От клиента приходит сразу 2 запроса одинаковых (причина пока неизвестна) с разницей во времени менее 1 сек и соответственно создаётся 2 заказа, но должен быть только один.
Все поля могут быть одинаковые, кроме orderId и даты создания, но когда создаётся 2 заказа, дата создания отличается менее чем на 1 секунду. Почему вообще может приходить 2 запроса и как можно решить проблему?


Так в чём дело-то? Если вам нужна заглушка, так и делайте заглушку. Пока не решите проблему в её источнике, сделайте проверку на этапе обработки заказа. Т.е. если есть два заказа от одного клиента с одинаковым набором товаров, обрабатываете заказ с наименьшим ID, а второй (третий и далее) помечаете как ложный.
вчера, 12:06    [22335316]     Ответить | Цитировать Сообщить модератору
Все форумы / PostgreSQL Ответить