@l4m3r

Как правильно применить транзакции и какой выбрать уровень изолированности?

Есть таблица folder (id, name, files_count). name -- уникальное.
Есть таблица file` (id, filename, folder_id).
Есть операция: Добавить файл в папку. Если папки нет, то создать её. Если есть, то просто инкрементируем у нее files_count.

В своём php так примерно (псевдокод):
1. Получаю запись $record = SELECT * FROM folder WHERE name = :name"
2. Если `$record === null`, то делаю INSERT INTO folder (name) VALUES (:name)
3. Если `$record !== null`, то делаю UPDATE folder SET files_count = files_count + 1 WHERE id = :record_id
4. Делаю INSERT INTO file (filename, folder_id) VALUES (:filename, :folder_id), где `folder_id` это или `last_insert_id` есть запись была только что добавлена, или `$record['id']`.

Как правильно всё это изолировать, чтобы при параллельном выполнении не возникла ситуация, когда 2 скрипта получив `$record === null`, попытались создать две одинаковые папки.
Просто обернуть все пункты одну транзакцию? (begin; select, insert / update, insert; commit;) ? А какой уровень изоляции?
  • Вопрос задан
  • 49 просмотров
Решения вопроса 3
Stalker_RED
@Stalker_RED
INSERT INTO files (name, files_count) VALUES ('example', 1)
   ON DUPLICATE KEY UPDATE files_count = files_count + 1
Ответ написан
inoise
@inoise
Solution Architect, AWS Certified, Serverless
Ну, для начала, а с чего вообще в структуре данных хранить число файлов? Я понимаю хранить их в кэше, но не в базе данных же, ну! Это операция агрегации с фильтром по родителю.

А если очень хочется то есть такая операция как обновление "версии". Храним у записи еще поле, например, timestamp с временем обновления или uuid как идентификатор версии. И обновляем запись в которой и id и это поле совпадают. Разно что поле тоже должно обновляться.

Кстати, files_count + 1 это плохая идея. Сюда стоит заносить агрегацию по родителю. Именно из-за параллелизма
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы