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

Кто-То может подсказать как можно сделать атомарно вот такую вещь? UPDATE

users SET balance=(SELECT SUM(amount) FROM transactions WHERE user_id=?)
Я же верно понимаю, что тут 2 запроса и если кто-то удалил параллельно из таблицы транзакций после того как в этом запросе посчиталась сумма, то я сохраню невалидный баланс.
Кроме блокировок можно это решить? Я знаю, что если мы будем запускать перерасчет после каждой операции изменения в таблицы transactions, то получим eventual consistency и баланс так или иначе будет верный. Мне бы понять можно ли просто запросом sql такой кейс решить

15 ответов

6 просмотров

Это будет в рамках одной транзакции, поэтому вы получите валидный результат на отметку времени начала транзакции. Если вы после каждого изменения таблицы transactions гарантированно выполняете такой запрос, то и баланс будет актуальный.

А как Вы собираетесь поддерживать в валидном состоянии баланс, если только не из приложения?

Кстати, почему бы не использовать триггеры на таблице transactions, которые будут автоматически обновлять поле balance в таблице users ? В случае триггеров счётчик не должен сбиваться.

Andrei Ilinskii
Кстати, почему бы не использовать триггеры на табл...

Вообще я бы через CTE соединил запросы вставки новых данных в transactions и обновление счётчика, чтобы не усложнять структуру базы.

Evgeny-Kungurov Автор вопроса
Andrei Ilinskii
Кстати, почему бы не использовать триггеры на табл...

Я ниразу их не юзал. Я разработчик который постоянно сталкивается с подобными вещами и кроме блокировок мне ничего на ум не приходит. Другие разработчики +- так же отвечают. Решил спросить у тех, кто хорошо в БД шарит

Evgeny Kungurov
Я ниразу их не юзал. Я разработчик который постоян...

Давай без триггеров вариант с CTE посмотрим. WITH data(user_id, amount) AS ( -- входящие параметры SELECT :user_id, :amount ), insert AS ( INSERT INTO transactions SELECT * FROM data ) UPDATE users SET balance = balance + data.amount FROM data WHERE users.user_id = data.user_id Чем не нравится?

Evgeny Kungurov
Надо обмозговать)

С триггерами по-сути тоже самое будет, просто часть с update уедет в триггер. Если задача держать поле balance в постоянном соответствии с суммой amount по таблице transactions, то вставка в транзакции и обновление счётчика должны идти в одной транзакции, по очевидным причинам )

Запросы всегда работают атомарно, а Вам тут нужно изоляция. К примеру, на уровне изоляции serializable это делается тривиально. Понятия "после / до" для параллельных транзакций не имеют прямого отношения к consistency, кстати.

Andrei Ilinskii
Кстати, почему бы не использовать триггеры на табл...

В триггерах нет никакой "магии", если Вы об этом. Т.е. если процедура обновления баланса ненадёжна сама по себе, и в триггере она будет работать не лучше.

Она и так атомарная. Баланс в любом случае на какой-то момент будет валидным -- и перестанет быть валидным сразу после этого момента. Более того, время, в течение которого этот баланс был валидным -- можэт быть строго 0, что не отменяет того, что значение поля balance после коммита соответствует балансу на какой-то момент в прошлом. Вопрос как сделать, чтобы этот баланс не менялся -- это другой вопрос. И ключевое здесь -- сколько вы хотите чтобы он не менялся и зачем вам это нужно.

Evgeny Kungurov
Я ниразу их не юзал. Я разработчик который постоян...

Если Вам важен результат этих транзакций — почитали бы Вы какой-то "фундаментальный" учебник про основные принципы ACID, честное слово. А то потом приходится (лично мне много приходилось) искать косяки в транзакциях и как-то устранять "кашу" в БД после "блокировщиков". ;(

Evgeny-Kungurov Автор вопроса
Yaroslav Schekin
Если Вам важен результат этих транзакций — почитал...

Есть пример? А то тонна инфы в инете, а толку не так много для меня. Я тоже знаю много разработчиков, у которых есть в компании DBA, который потом всем пальчиком показывает, но у меня нет такого спеца.

Evgeny Kungurov
Есть пример? А то тонна инфы в инете, а толку не т...

Пример учебника, в смысле? Я сходу не помню... ну вот "Database system concepts", например. > у которых есть в компании DBA Заниматься такими вещами — вообще не дело DataBase Administrator. Это базовые знания, умения и ответственность разработчика баз данных, если что. ;)

Andrei Ilinskii
Давай без триггеров вариант с CTE посмотрим. WITH ...

> и изоляция там по умолчанию read_commited. Значит, см. вариант 2. > Меня лишь интересовало как сделать без блокировок сделать правильные цифры. Пути, показанные тут https://t.me/pgsql/346283 и тут https://t.me/pgsql/346286 (если "..." заполнить аналогично первому примеру), на первый взгляд верные. Это если считать, что других (пишущих) транзакций, затрагивающих эту таблицу, в базе не бывает (взаимодействия с ними нужно разбирать отдельно). Собственно, это ещё одна проблема RC в нетривиальных случаях — для добавления ещё одного вида транзакции в худшем случае придётся подумать, как она будет взаимодействовать с N уже существующих. > Вот первая статья Да не читайте Вы эту чушь "статьи" (почти все те, что я в когда-либо видел, содержали грубые ошибки, например) — читайте учебники и документацию.

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

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

@Aiwan что такое база образца?
Alexey
27
Не многие знают, а кто знает, тот уже успел забыть, что в далёком 2004 году эта игра произвела настоящий фурор, настолько революционной была технология, применяемая для её соз...
ICCID
4
Хотя у меня сейчас есть более сложная задача, вот её думаю: как объяснить челу переходного возраста противоположного полу, обучающегося в польском колледже (а-ля наш техникум)...
Вячеслав Кузьменко
15
коллеги, добрый вечер! А никто не знает как модальная форма может себя закрыть? Ну допустим модальная форма определила, что смысла ей работать нет и хочет вернуть modalResult...
Михаил
83
Добрый день Хочу начать обучение языку, не являюсь представителем it, буду благодарна за помощь, совсем пока не понимаю ничего) Подскажите, пожалуйста, где можно начать первы...
Sara Lala
30
верно что я могу удалить эти addq и subq т.к. со стеком никакого взаимодействия нет (исключая call)?
Michael
16
Hi Everyone! To all Are you Looking for Interview Support at the Lowest Price? Look no further! Then contact us We offer Interview Support for a low cost variety of technol...
Rambabu Nallamilli
3
средствами IBX как-то можно выполнить запрос insert ... returning?
Igor
31
Hi there everyone Is there anyone who have not started hamster bot yet? I need only one, I'll be glad if you do this for me DM if you haven't yet
Mehrshad
53
А если изначально бот работал так : есть сайт онлайн школы. У каждого ученика свой кабинет. Где он авторизуется по своим данным. И уже в кабинете, на самом сайте делает оплату...
Денис 💡 Фрилансер
13
Карта сайта