172 похожих чатов

Вечер добрый. Как бороться с race condition? В несколько потоков

клиентский код пытается заселектить, обновить или вставить данные. В таблице уникальный индекс на эти данные. При многопоточном доступе и select for update проскакивает вставка одних и тех же данных. Естественно падает по ограничению целостности. Можно как-то заблокироваться, но не на всей таблице?

8 ответов

10 просмотров

Может это нормально?

Viktor-AB Автор вопроса
Sergey Gr
Может это нормально?

Нужно заблокироваться на строке и не селектить, пока другая транзакция не отпустит.

Вариант 1. Использовать везде SERIALIZABLE (прочитав в документации, как именно), и получить надёжное решение проблемы. Вариант 2. Прочитать и осознать (попробовать на примерах) всю документацию про изоляцию в PostgreSQL (про serializable можно при этом не читать), понять механизмы, подумать о возможных взаимодействиях в конкретном случае, придумать и протестировать подход... и, если Вы хоть что-то сделаете неправильно, то проблема просто будет появляться значительно реже. ;) Для варианта 2 есть набор паттернов, которые часто помогают, а иногда — нет, если что.

Непонятно, в чем проблема? Вы делаете select for update, так? Это значит, что запрос заблокируется, если часть строк, которые вы выбираете, взяты другим select for update. Поэтому тут 2 варианта: 1) вы выбираете разные строки двумя транзакциями, в которых делается select for update, и изменяете их на одни и те же строки, поэтому получаете ошибку 2) либо просто делаете select for update и изменяете данные на те, которые уже вставлены. Выглядит так, что проблема либо в логике приложения, либо в том, что вы не хотите обрабатывать ошибки.

Viktor-AB Автор вопроса
Aleksey Stavrov
Непонятно, в чем проблема? Вы делаете select for u...

Не совсем. Для примера пытаюсь в несколько потоков в одной транзакции сделать select for update и если нет строки, то вставить. Ожидал, что будет работать блокировка, но по факту проскакивают попытки вставить одно и то же в разных транзакциях.

Viktor AB
Не совсем. Для примера пытаюсь в несколько потоков...

А unique constraint над суррогатным ключем или над чем-то существенным?

Viktor-AB Автор вопроса
Sergey Gr
А unique constraint над суррогатным ключем или над...

В синтетическом примере на все поля, кроме ключа.

Viktor AB
Не совсем. Для примера пытаюсь в несколько потоков...

Можете попробовать уровень изоляции serializable поставить, но его нужно будет включать вообще для всех транзакции. Тогда у вас эта ошибка скорей всего уйдёт и будет другая ошибка - ошибка сериализации данных. Более детально тут невозможно что-то подсказать, не поняв логику работы.

Похожие вопросы

Обсуждают сегодня

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта