2016-01-17 3 views
1

ОбзорКак справиться с проблемами параллелизма с использованием транзакций Yii2 и MySQL?

Рассмотрим следующие детали:

  1. У нас есть таблица с именем user. В нем находится столбец с именем wallet.
  2. У нас есть таблица с именем walletAction. Мы вставляем новую запись в каждый действие кошелька, который делает пользователь. Эта таблица действует как некоторый журнал в базе данных с некоторыми вычислениями.
  3. У нас есть команда CRON, которая обновляет каждые N минут. Каждое действие CRON получает некоторые данные с использованием автономного API и «вставляет» новую запись walletAction. В это время он обновляет user. wallet.
  4. A user можно купить с нашего сайта. Когда user нажимает кнопку покупки, мы вставляем новую запись walletAction и меняем user. wallet колонка.

Проблема

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

Мне нужна какая-то «блокировка» при выполнении обновления CRON или что-то в этом роде.

Вопросы

  1. Должен ли я бояться этой ситуации?
  2. Как я могу избежать этой проблемы?
  3. Могу ли я избежать этой проблемы, используя транзакции MySQL?
  4. Какой уровень изоляции я должен использовать, и в каком случае следует использовать его? (В команде CRON или в действии user при нажатии на кнопку купить?)
+0

Вы, кажется, не понимаете этого термина; вы обеспокоены проблемами ** параллелизма **. – Keale

+1

[возможно, сможет помочь] (http://stackoverflow.com/questions/1195858/how-to-deal-with-concurrent-updates-in-databases) – Keale

ответ

0

кажется, что мы не имеем параллелизм на php как в GO или Java. Вы можете реализовать какой-то технический трюк, но почти из них возникли новые проблемы для вас :). Для решения вашей проблемы я предлагаю вам использовать optimistic lock. Для получения дополнительной информации вы можете найти http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#optimistic-locks.

+0

Не помогу, потому что, насколько я знаю блокирует только на beforeSave до afterSave. Поэтому, если мне нужно изменить несколько таблиц (записей), это будет проблемой, потому что мне нужно заблокировать их все, а не просто «один в момент обновления». Так что это не может мне помочь. – user1954544

0

Да, в этом случае я бы рекомендовал использовать trasactions с самым сильным уровнем изоляции yii\db\Transaction::SERIALIZABLE. Этот уровень должен предотвращать «фантомные чтения» и «неповторяющиеся чтения».

Кроме того, я рекомендую использовать транзакции всегда, когда вы выполняете более 1 связанных изменений, поскольку это помогает поддерживать согласованность БД. Это может предотвратить проблему при получении некоторого исключения PHP после успешной вставки новых строк в walletAction, но до user.wallet.

Смежные вопросы