Выбор-блокировка в Rails с MySQL

95
11

Ищите лучший совет:


Предположим, что у меня есть объект Account с атрибутом limit. Каждый день может быть n Платежей с суммой их сумм до лимита учетной записи. При создании нового платежа он проверяет, не превышает ли он сумму + суммы других платежей за день, и сохраняет или записывает ошибку.


Теперь предположим, что у меня есть счет с лимитом 100 $, и одновременно создаются два платежа в 99 $. Каждый из них сделает выбор, увидит, что ничего не существует, и приступим к сохранению, в результате чего сохраняется общая сумма в 198 $.


Чем вы занимались? Я думал о выпуске блокировки записи в таблице платежей в начале транзакции, но это выглядит довольно тяжело, потому что я действительно забочусь о том, чтобы платежи, принадлежащие определенной учетной записи, не были прочитаны другими транзакциями. Есть ли другие варианты, лучшие способы решения этой ситуации?

спросил(а) 2010-08-17T15:36:00+04:00 9 лет, 11 месяцев назад
1
Решение
79

Я думал о выпуске блокировки записи в таблице платежей в начале транзакции, но это похоже на выход из



Предполагая, что вы уже говорите о транзакциях, я предполагаю, что вы не используете MyISAM, но вместо этого InnoDB или какой-либо другой движок, который уже поддерживает транзакции.


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


В описываемом вами случае использования транзакции с уровнем изоляции SERIALIZABLE блокируются для чтения и записи. Кроме того, он автоматически блокирует только записи, которые вы прочитали (даже если вы запрашиваете диапазоны), поэтому оставляя оставшиеся записи свободными для манипуляций.

Через уровень изоляции "SERIALIZABLE", когда вы читаете информацию из таблицы, любые попытки обновить или прочитать эти записи должны будут дождаться завершения этой транзакции. Кроме того, убедитесь, что вы прочитали, прежде чем обновлять одну транзакцию, чтобы убедиться, что вы работаете с правильным значением.


Здесь вы можете узнать больше об уровнях изоляции:
http://en.wikipedia.org/wiki/Isolation_(database_systems)
http://www.databasejournal.com/features/mysql/article.php/3393161/MySQL-Transactions-Part-II---Transaction-Isolation-Levels.htm


Вы можете узнать, как настроить уровень изоляции ваших транзакций здесь:
http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html

ответил(а) 2010-08-17T17:30:00+04:00 9 лет, 11 месяцев назад
54
ответил(а) 2010-08-17T15:41:00+04:00 9 лет, 11 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема