powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Зачислить заработки по итогу дня (запутался в транзакциях)
5 сообщений из 5, страница 1 из 1
Зачислить заработки по итогу дня (запутался в транзакциях)
    #40000332
AndryG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В игрушке персы на протяжении дня зарабатывают клановые очки. По концу дня нужно разнести заработанные игроками очки по кланам. Также необходимо списать часть очков - "налог" - с клана (дифф. по уровню).

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
-- таблица с заработками игроков
CREATE TABLE clanpoints (
  id INTEGER NOT NULL AUTO_INCREMENT,
  user_id INTEGER DEFAULT NULL,  -- кто заработал или null, если очки выданы клану
  source_id INTEGER NOT NULL,  -- ссылка "где заработано" / "за что списано"
  clan_id INTEGER NOT NULL,  -- клан получатель
  points INTEGER NOT NULL,  -- сумма очков
processed integer default null  -- флаг обработки записи
)

-- таблица для ежедневных зачислений очков
create table clan(clan_id, points)



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

Выбираю список кланов-получателей и дальше для каждого клана в отдельной транзакции (read committed)
1 сформировать уникальное число (случайное число либо insert в левую таблицу-генератор)
2 записать это число в поле clanpoints.processed текущего клана
3 выбрать сумму очков в измененных записях
4 изменить остатки в clan.points
5 вычитать новое значение clan.points и поправить уровень (уровень зависит от к-в очков)


Дополнительно надо выставить списание налога, добавив запись с "отрицательным заработком" в clan.points, который учтется в следующие сутки.

Это нормально так делать или я нагородил вагон полной фигни ?
...
Рейтинг: 0 / 0
Зачислить заработки по итогу дня (запутался в транзакциях)
    #40000337
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndryG
или я нагородил вагон полной фигни ?
Скорее да, чем нет. Теоретически это делается одним, пусть и достаточно навороченным, запросом.
...
Рейтинг: 0 / 0
Зачислить заработки по итогу дня (запутался в транзакциях)
    #40000458
AndryG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Теоретически оно понятно. Подскажите, пжлст, как провести зачисление без потерь.
...
Рейтинг: 0 / 0
Зачислить заработки по итогу дня (запутался в транзакциях)
    #40000568
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndryG , делайте online fiddle (например, на https://dbfiddle.uk/?rdbms=mysql_8.0 ) и давайте для него эталонный ответ - будем смотреть-пробовать.
...
Рейтинг: 0 / 0
Зачислить заработки по итогу дня (запутался в транзакциях)
    #40000666
AndryG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Плюнул на высокие материи параллелизма и наваял одним запросом.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
update -- select * from
  (select 
    sum(c.points) points,
    c.clan_id,
    concat(',', GROUP_CONCAT(c.id), ',') ids
  from (select * from clanpoints where processedkey is null limit 200) c
  where c.processedkey is null
  group by c.clan_id) t  
  join clans c
    on c.id = t.clan_id
  join clanpoints p
    on position(concat(',', p.id, ',') in  t.ids) > 0
    and p.clan_id = t.clan_id
set
  c.clanpoints = c.clanpoints + t.points,
  p.processedkey = unix_timestamp()



Хотел на этой задачке вникнуть, как по-взрослому разруливают блокировки и т.п., да не вышло.
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Зачислить заработки по итогу дня (запутался в транзакциях)
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]