Flight404
@Flight404
начинающий PHP - программист

Как заблокировать одновременное редактирование записи в БД на laravel?

Добрый День! Как реализовать запрет на одновременное редактирование записи в БД MySQL c помощью LARAVEL? Т.е если один пользователь редактирует запись, то другому должно выдаваться сообщение, что запись в данный момент заблокирована. Так же необходимо предусмотреть ситуацию, что пользователь не сохранит изменения, а просто закроет браузер. Тогда блокировку тоже необходимо снять! Админы могут работать как на PC так и на мобильном устройстве (а в браузерах android не отслеживается закрытие вкладки).
  • Вопрос задан
  • 804 просмотра
Пригласить эксперта
Ответы на вопрос 5
hePPer
@hePPer
можно попробовать обойтись без блокировки, если ситуация не очень частая.
давать нескольким юзерам возможность получить запись для изменения, при этом добавить в таблицу поле времяИзменения - куда заносить время последней модификации строки. при внесение в базу изменений проверять ключ обновляемой записи и время модификации (update .... where id=1 and lastEdit='lasteditdate'). если время модификации не совпало - то сообщить юзеру что запись которую он редактирует уже изменена кем то и показать ему новые изменения.
Ответ написан
@Kostik_1993
Самый четкий вариант по вашим требованиям это вебсокет, если страница открыта ставится статус что кто-то уже работает с записью, при открытии новой вкладки проверяется идет ли сейчас редактирование

Никакие ключи в базе для вашей ситуации не подойдут

Второй менее правильный использовать кеш, при открытии пишете в него по ключу post-edit-{$id} значение тру например на 1минуту, а на форме редактирования вам нужно поставить таймер через указанный некоторый отрезок времени, но не больше того что указан в кеше и отправлять на сервер id поста и обновлять вашу запись в кеше, при открытии формы редактирования смотрите в если Cache::has("post-edit-{$id}") == true выводите нотис что кто-то уже редактирует

В идеале валидацию нужно сделать на клиенте чтобы страница не обновлялась и вам не пришлось еще писать проверку того что пост редактирует текущий пользователь и для него нотис не нужен
Ответ написан
Flight404
@Flight404 Автор вопроса
начинающий PHP - программист
Прочитав комментарии и ответы, я понял что не знаю и не умею использовать вэбсокет. И сделал такой вариант. В БД есть поле locked_at, где хранится время редактирования и поле locked_by, где хранится id пользователя. Соответственно если другие пользователи пытаются отредактировать или удалить запись, то идет проверка в бд если текущее время больше 1 минуты времени в locked_at, то это сделать можно. А до тех пор, пока пользователь редактирует запись, идет ajax запрос каждые 30с, который обновяет поле locked_at. И соответственно когда вкладка закрыта или сохранена, то ajax не летит и через 1 минуты первый кто достучится получит возможность редактировать.
Ответ написан
Есть два идеологически разных варианта реализации:
1. Главный тот, кто первым открыл форму редактирования (этот вариант описали вы выше). Требует дополнительных полей вроде locked_at, аякса и т.п.
2. Главный тот, кто первый изменил. Два пользователя открывают форму, редактируют. Первый сохраняет без проблем, а второй при сохранении получает сообщение что запись уже изменена ранее. Можно ему diff показать или еще что-нибудь... (такой вариант описал Vladimir S). Здесь никаких доп. полей не нужно, достаточно просто проверить перед сохранением что поле updated_at не изменилось.
Ответ написан
Wolfnsex
@Wolfnsex
Если не хочешь быть первым - не вставай в очередь!
Как реализовать запрет на одновременное редактирование записи в БД MySQL c помощью LARAVEL?
Добавить флаг (колонку в БД), подобный функционал был придуман и применяется ещё с лохматых годов, соотв. при попытке начать редактирование записи - этот флаг должен проверяться.

Чуть более сложный вариант - блокировать запись на уровне БД, не знаю насколько он Вам подойдёт и нужен ли вообще, но такой вариант тоже есть.

А в браузерах android не отслеживается закрытие вкладки!!!
Я Вам по секрету скажу, закрытие вкладки даже в браузерах "не адроид" не всегда можно отследить и всецело полагаться на что-то подобное я бы не стал. Один из вариантов "надёжного" отслеживания наличия "клиента на линии" - выглядит примерно так:
1. Поднимаете сервер веб-сокетов, он же будет контроллировать блокировку той или иной записи в БД
2. Каждые N-секунд отсылаете клиенту PING-запрос, если клиент не ответил (X раз подряд, и/или в течении Y секунд) сбрасываете блокировку (ну и можно заодно попробовать клиенту уведомление отослать, или прямо у клиента в браузере повесить индикатор активности соединения). Нечто аналогичное используют множество сетевых сервисов, например IRC- серверы/клиенты.

P.S. Это наиболее простые и эффективные варианты. Непосредственного отношения к Laravel они не имеют и с учётом контекста вопроса - и не должны.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы
10 дек. 2018, в 22:25
2000 руб./за проект
10 дек. 2018, в 21:28
27000 руб./за проект