У меня есть два приложения exporter
и payment_handler
exporter
выполняет SELECT * FROM orders WHERE status="PAID"
, обрабатывает строки (около 5 минут) и, наконец, UPDATE orders SET status="EXPORTED" WHERE status="PAID"
payment_handler
выполняет UPDATE orders SET status="PAID" WHERE status="UNPAID"
Без изоляции транзакции это приведет к неправильному обновлению данных при выполнении payment_handler
, когда exporter
обрабатывает строки: оператор UPDATE
экспортера помечает заказы как экспортированные, которые оператор SELECT
не выбирал ранее.
Если я оберну экспортер в транзакции и сделаю SELECT
с квалификатором FOR UPDATE
, payment handler
будетзаблокирован до exporter
, потому что MySQL не разрешает новые вставки status="PAID"
.Но обработчик платежей не должен быть заблокирован на такой длительный срок.
Мой текущий обходной путь - избежать транзакции и создать собственный «снимок» данных: exporter
создает временную таблицу export_ids
иделает вставку, как это: INSERT INTO export_ids SELECT id FROM order WHERE status="PAID"
.Все последующие операции SELECT и UPDATE для таблицы order
в exporter
присоединят / отберут таблицу export_id
.С точки зрения производительности и хранилища это работает нормально, поскольку в export_ids
будет только около 100 тыс. Записей для одного экспорта.
Но мне интересно, правильно ли я использую уровни транзакций MySQLs и есть лиЕсть ли лучший способ достичь поведения?