2015-02-27 2 views
0

У меня есть веб вид, подобный следующему:Блокировка таблицы (? Или использовать транзакцию) для оплаты

def process_payment(request, user): 
    amount = 'SELECT amount FROM table where user=user' 
    PayUser(user, amount) 
    return 'OK 

Проблема с этим состоит в том, что если кто-то просил же оконечных тысячи раз (пытаясь обмануть систему), возможно, что user.get_balance() вернет то же значение, и пользователь будет получать многократно.

Как я могу установить «блокировку», чтобы предотвратить это?

ответ

1

Существует несколько способов установки блокировки в этом случае. Способ, которым я работал раньше, заключается в следующем: каждый рабочий поток, который изменяет значение, должен установить GUID рабочего в строке таблицы, а затем проверить, установлен ли GUID для их идентификатора GUID. Только тогда они могут их обработать. Ни один другой рабочий не может обработать строку до тех пор, пока GUID не будет очищен, и это будет сделано только после завершения процесса. В рабочем процессе:

  1. Получить сумму и увидеть, что пользователь должен быть оплачен обеспечение работника GUID является нулевым
  2. Работник блокирует строку, используя код GUID
  3. работник проверяет GUID совпадает, если нет, то прерывает
  4. Рабочий обновляет значение и устанавливает идентификатор GUID на нуль.

Вы также можете добавить time_locked, а затем еще один процесс, чтобы сбросить идентификаторы GUID до нуля, если строка была заблокирована более 10 минут. Таким образом, если работник терпит неудачу, он исправит себя.

Поскольку база данных соответствует требованиям ACID, это будет работать.

Для генерации GUID посмотрите библиотеку uuid.

+0

Это похоже на отличную идею. Было бы хорошо, если бы я положил 'payment_guid_lock' в пользовательскую таблицу? Или нужно зайти в новый стол? – David542

+1

Вы можете или можете поместить его в таблицу с суммой, так как эта транзакция касается сумм. Извините, вы не блокируете всю таблицу, вы просто блокируете строку, чтобы добавить новый столбец с идентификатором GUID. –

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