Несколько операторов обновления в одной строке в одно и то же время - PullRequest
1 голос
/ 12 октября 2019

У меня есть сценарий, в котором я получаю запрос на такси от клиента и отправляю запрос на погрузку нескольким водителям. Теперь представьте, что если два водителя, получившие запрос, одновременно нажали кнопку «Принять», то какой водитель получит поездку.

У меня есть таблица поездок со столбцами. (Boolean).

На данный момент я вызываю API, как только нажимается кнопка «Принять». Этот API-интерфейс запроса GET проверяет, выполнена ли поездка или нет. Если да, я показываю водителю сообщение о том, что поездка уже выполнена, иначе я нажимаю другой запрос POST API, который обновляет выполненное значение в БД до true, а также обновляет driver_id.

Теперь перейдем к нашему сценарию, когда обадрайверы будут нажимать «Принять» в то же время, когда будут выполнены два запроса GET, и оба получат «Не выполнено», после чего оба отправят запрос POST. Теперь я запутался, чьи данные будут обновляться в БД.

Я использую PHP в качестве серверной части с MYSQL для базы данных.

Ответы [ 2 ]

4 голосов
/ 12 октября 2019

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

UPDATE ride 
SET driver_id = :driver_id, fulfilled = 1 
WHERE ride_id = :ride_id AND fulfilled = 0

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

0 голосов
/ 12 октября 2019

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

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

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

Интересно, что это средство уже встроено в большинство реляционных баз данных, поэтому вам не нужно беспокоиться о двух транзакциях, обновляющих базу данных одновременно. Тем не менее, интересной областью исследования является то, как управлять очередями транзакций (например, расставлять приоритеты ожидающих транзакций) в этом сценарии.

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