Обработка транзакций MySQL с использованием Ignore (или аналогичного) и уникальных идентификаторов - PullRequest
0 голосов
/ 28 июня 2010

Я использую MySQL + PHP. У меня есть некоторый код, который генерирует платежи из таблицы автоматических платежей в зависимости от того, когда они должны быть выполнены (чтобы вы могли планировать будущие платежи ... и т. Д.). Автоматический сценарий запускается после активности на сайте и иногда запускается дважды одновременно. Чтобы избежать этого, мы генерируем uuid для платежа, когда для определенного автоматического платежа может быть только n-й платеж. Мы также используем транзакции для инкапсуляции всего процесса генерации платежей.

Как часть этого, нам нужно, чтобы вся транзакция потерпела неудачу, если есть дубликат uuid, но получение фактической ошибки базы данных покажет ошибку пользователю. Могу ли я использовать Insert Ignore в платежной вставке SQL? Будет ли предупреждение убить транзакцию? Если нет, как я могу завершить транзакцию при наличии дубликата uuid?

Чтобы уточнить: если INSERT завершается неудачно, как я могу заставить его не генерировать ошибку остановки программы, а завершить / откатить транзакцию?

Имейте в виду, вставка завершится неудачей при коммите, а не при первоначальном выполнении в php.

Большое спасибо!

Ответы [ 2 ]

1 голос
/ 01 марта 2011

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

Я предполагаю, что вы получите UUID из другой таблицы перед обработкой и вставкой.Вы можете использовать транзакцию, а затем SELECT ... FOR UPDATE, когда вы читаете записи.Таким образом, прочитанные вами записи заблокированы.Когда вы получите все данные, обновите столбец status до «обработано» и COMMIT транзакция.Наконец, убедитесь, что процесс не читает записи со статусом «обработан».

Надеюсь, это поможет ...

0 голосов
/ 13 января 2015

Просто наткнулся на это.И это старый вопрос, но я постараюсь дать ответ.

Во-первых: убедитесь, что ваша платежная работа выполняется только по одному за раз.Думаю, это может избавить вас от многих проблем.

Второе: если ваш оператор обновления не работает в php, поместите его в блок try-catch.Таким образом, ваш запрос mysql не будет выполнен, но ошибка не будет показана пользователю, и вы можете справиться с этим.

try {
   ... your mysql code here ....
} catch (Exception $e) {
   ... do whatever needs to be done in case of problem ...
}

Имейте в виду, что существует множество возможных источников исключений.Никогда не принимайте вставку как причину как должное.

...