Аукционная ставка - будет ли SELECT LOCK IN SHARE MODE сохранять информацию самой последней? - PullRequest
2 голосов
/ 26 января 2012

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

Я пришел к использованию SELECT LOCK IN SHARE MODE, в котором говорится, что If any of these rows were changed by another transaction that has not yet committed, your query waits until that transaction ends and then uses the latest values.

http://dev.mysql.com/doc/refman/5.1/en/innodb-locking-reads.html

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

Тем не менее, я прочитал, что могут быть опасные проблемы взаимоблокировки, когда два пользователя пытаются сделать ставки одновременно, и ни один запрос не может поддерживать блокировку. Поэтому я также рассмотрел использование SELECT FOR UPDATE, но это также отключит все чтения, в которых я совершенно не уверен.

Если бы кто-нибудь мог пролить свет на эту проблему, которая была бы признательна, если бы вы могли предложить любую другую базу данных, такую ​​как NoSQL, которая была бы более подходящей, то это было бы очень полезно !!!

РЕДАКТИРОВАТЬ: Это, по сути, проблема параллелизма, когда я не хочу проверять текущую ставку с неверными / старыми данными, что может привести к «потерянному обновлению» определенных ставок.

1 Ответ

3 голосов
/ 26 января 2012

Само по себе два одновременных обновления не приведет к взаимоблокировке, а только к временной блокировке. Давайте назовем их Bid A и Bid B.

Хотя мы рассматриваем их одновременно, сначала нужно получить блокировку. Мы скажем, что A добирается туда на 1 мс быстрее.

A получает блокировку для рассматриваемой строки. B отправляет запрос на блокировку в очередь и должен дождаться снятия блокировки, принадлежащей A. Как только блокировка A снята, B получает блокировку.

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

Если вам нужно проверить ставку в режиме реального времени, вы можете:

A. Используйте соответствующий уровень изоляции транзакции (повторяемое чтение, вероятно, по умолчанию в InnoDB) и выполняйте выбор и обновление в явной транзакции.

BEGIN TRAN
    SELECT ... FOR UPDATE
    IF ...
    UPDATE ...
COMMIT

B. Выполните свою логику проверки в самом операторе Update. Другими словами, создайте запрос UPDATE, чтобы он влиял на строки только тогда, когда текущая ставка меньше новой ставки. Если записи не были затронуты, ставка была слишком низкой. Это возможный подход и сокращает работу с БД, но имеет свои соображения.

UPDATE ...
WHERE currentBid < newBid

Лично я бы выбрал А, потому что я не знаю, насколько сложна ваша логика.

A repeatable read уровень изоляции гарантирует, что при каждом прочтении данной записи в транзакции значение гарантированно будет одинаковым. Он делает это, удерживая блокировку строки, которая не позволяет другим обновлять данную строку до тех пор, пока ваша транзакция не выполнит фиксацию или откат. Одно соединение не может обновить вашу таблицу, пока последняя не завершит свою транзакцию.

Суть в том, что ваш выбор / обновление будет атомарным в вашей БД, поэтому вам не придется беспокоиться о потерянных обновлениях.

Что касается параллелизма, ключ в том, чтобы ваши транзакции были максимально короткими. Садись, уходи. По умолчанию вы не можете прочитать обновляемую запись, потому что она находится в неопределенном состоянии. Эти обновления и чтения должны занимать небольшие доли секунды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...