Как на высоконагруженном проекте правильно делать запросы к БД?

12
PN
На сайте с 22.08.2012
Offline
103
1542

Вопрос к программистам, у которых есть опыт работы с высоконагруженными порталами. Как Вы списываете деньги с баланса, если баланс может параллельно изменяться другим скриптом (например, по Крону)? Используете ли Вы SELECT...FOR UPDATE?

Насколько правильна такая конструкция?

UPDATE users SET balance=balance-200 WHERE id=:id AND balance>=200
Мой совет помог? Не скупись! Bitcoin 1Lseddet1o1B6odgXQHbGaWGwRkt1Db8Ef Ethereum 0x450f1a17461e25194B7F9226cDEe70173F39e1e1
S
На сайте с 23.05.2004
Offline
316
#1

У себя в транзакции делаю. Т.е. в ней читаю баланс, проверяю на нужную сумму, создаю запись лога на уменьшение суммы, изменяю баланс.

Тут даже дело не в нагруженном проекте. Просто банально бывает от юзера по 2 одинаковых запроса прилетает в момент. Поэтому в транзакции можно успеть отследить дубль.

Это просто подпись.
PN
На сайте с 22.08.2012
Offline
103
#2
Stek:
У себя в транзакции делаю. Т.е. в ней читаю баланс, проверяю на нужную сумму, создаю запись лога на уменьшение суммы, изменяю баланс.

Тут даже дело не в нагруженном проекте. Просто банально бывает от юзера по 2 одинаковых запроса прилетает в момент. Поэтому в транзакции можно успеть отследить дубль.

Транзакция это типа такого?


query("START TRANSACTION");
query("...");
query("COMMIT");
LEOnidUKG
На сайте с 25.11.2006
Offline
1725
#3

Строчка в innodb уже блокируется при операции, уже АВТОМАТИЧЕСКИ идёт транзакция, вам ничего делать не нужно. Т.е. запросы к этой строчке идут последовательно.

В myisam так вообще вся таблица блокируется с такими операциями.

✅ Мой Телеграм канал по SEO, оптимизации сайтов и серверов: https://t.me/leonidukgLIVE ✅ Качественное и рабочее размещение SEO статей СНГ и Бурж: https://getmanylinks.ru/
PN
На сайте с 22.08.2012
Offline
103
#4
LEOnidUKG:
Строчка в innodb уже блокируется при операции, уже АВТОМАТИЧЕСКИ идёт транзакция, вам ничего делать не нужно. Т.е. запросы к этой строчке идут последовательно.

В myisam так вообще вся таблица блокируется с такими операциями.

Как это в InnoDB она блокируется? Хотите сказать, что тут


SELECT * FROM users WHERE id=:id
UPDATE users SET balance=:balance WHERE id=:id

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

LEOnidUKG
На сайте с 25.11.2006
Offline
1725
#5

При чём тут SELECT?!

Вы говорите про:

может параллельно изменяться другим скриптом

Не может он изменится. Операции UPDATE блокируют строчку на ЗАПИСЬ. И выполняются последовательно.

Также опешите проблему из-за которой у вас возник вопрос? Баланс в минус уходит или что?

PN
На сайте с 22.08.2012
Offline
103
#6
LEOnidUKG:
При чём тут SELECT?!

Вы говорите про:



Не может он изменится. Операции UPDATE блокируют строчку на ЗАПИСЬ. И выполняются последовательно.

Также опешите проблему из-за которой у вас возник вопрос? Баланс в минус уходит или что?

Про UPDATE я знаю, а я говорю, что когда несколько таблиц и нельзя все запихнуть в один запрос, то лучше использовать транзакцию, чтобы не было изменений строчки между запросами.

LEOnidUKG
На сайте с 25.11.2006
Offline
1725
#7

Вот уже вырисовывается несколько таблиц :)

Просто мы же не можем знать, что у вас там за структура и т.д.

Конечно можно использовать START TRANSACTION, но если честно держать баланс в разных таблицах ИМХО как-то неверно.

PN
На сайте с 22.08.2012
Offline
103
#8
LEOnidUKG:
Вот уже вырисовывается несколько таблиц :)

Просто мы же не можем знать, что у вас там за структура и т.д.

Конечно можно использовать START TRANSACTION, но если честно держать баланс в разных таблицах ИМХО как-то неверно.

да баланс то в одной, ну я приведу конкретный пример, когда сам разберусь со структурой:)

Оптимизайка
На сайте с 11.03.2012
Offline
396
#9

При операциях с деньгами лучше вообще update не использовать, а то потом концов не найдете, куда деньги пропали :) только insert: приход +100, расход -100. Баланс - складываете (сумму можно закешировать, чтобы не считать каждый раз).

⭐ BotGuard (https://botguard.net) ⭐ — защита вашего сайта от вредоносных ботов, воровства контента, клонирования, спама и хакерских атак!
I
На сайте с 21.09.2011
Offline
35
#10
Оптимизайка:
При операциях с деньгами лучше вообще update не использовать, а то потом концов не найдете, куда деньги пропали :) только insert: приход +100, расход -100. Баланс - складываете (сумму можно закешировать, чтобы не считать каждый раз).

Хоть один умный человек посоветовал как правильно делать)☝

12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий