Должен ли я использовать собственную таблицу блокировок с MySQL? - PullRequest
1 голос
/ 12 июня 2011

Я занимаюсь разработкой относительно простого, настраиваемого веб-приложения с базой данных MySQL MyISAM на серверной части.Так или иначе, я хочу избежать классической проблемы перезаписи параллелизма, например, что пользователь A перезаписывает правки пользователя B, потому что B загружает и отправляет некоторую форму редактирования до завершения A.

Вот почему я хотел бы как-то заблокировать строку наотображение формы редактирования.Однако ...

  • Как я уже сказал, я использую MyISAM, который, насколько я могу судить, не поддерживает блокировки на уровне строк.Кроме того, я не уверен, рекомендуется ли практиковать удержание «настоящих» блокировок MySQL в течение нескольких минут.
  • Я не очень много знаю о транзакциях, но из того, что я видел, похоже,они предназначены для использования внутри одного соединения.
  • Использование какой-либо системы слияния конфликтов, такой как в Git, на самом деле не вариант.

Строки останутся заблокированными на несколько минут,Параллельность очень мала: в любое время приложение используют полдюжины пользователей.

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

Будет ли это работать?Что я должен сделать, чтобы избежать тупиков, прямых блокировок и прочего?

Ответы [ 2 ]

3 голосов
/ 12 июня 2011

Вы можете реализовать блокировку, проще всего было бы добавить два поля к данным, которые вы хотите заблокировать (lock_created Datetime, locked_by int).Затем на странице редактирования (и, вероятно, также на кнопке редактирования) вы проверяете, не является ли (lock_created + lock_interval)

Одна сложная часть этого состоит в том, что делать, когда кто-то редактирует, но не может отправить в течение интервала блокировки.Итак:

  1. Значение lock_interval составляет 2 минуты.
  2. В 0:00 Алиса блокирует страницу, что-то редактирует, но получает телефонный звонок и не передает свои изменения
  3. В 2:30 Боб проверяет страницу, получает измененияблокировка, потому что блокировка Алисы истекла, и редактирует
  4. В 3:00 Алиса возвращается к своему компу, нажимает отправить -> конфликт.

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

Примечание к структуре таблицы: вы можете создать таблицу 'lock' с полями 'table_name, row_id, lock_created, locked_by', но это, вероятно, будет не самым простым способом, поскольку объединение имен переменных таблицсложный и запутанный.Кроме того, вероятно, бесполезно иметь одно место для хранения всех замков.Для простого механизма, я думаю, что добавить однородные поля в каждую таблицу, в которой вы хотите реализовать механизм блокировки, проще всего.

0 голосов
/ 12 июня 2011

Вы абсолютно не должны использовать блокировки на уровне строк для этого сценария.

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

...