Предотвращение одновременной перезаписи при редактировании строки MySQL через PHP

Я не уверен, как это кратко сказать, поэтому я объясню это через ситуационный контекст.

Пользователь-А решает, что хочет изменить строку MySQL через HTML-форму. Одновременно User-B решает, что он также хочет изменить одну и ту же строку MySQL таким же образом.

Мы будем говорить, что строка MySQL - это текстовое поле, содержащее текст, 'Can\'t touch this'

Два пользователя не знают о намерениях друг друга.

Пользователь-A вносит существенные изменения в строку MySQL и сохраняет их в базе данных. MySQL-строка становится 'Can\'t touch this was a popular track by the Hip-Hop artist M.C. Hammer.'

Пользователь-B делает незначительное изменение в строке MySQL и сохраняет его в базе данных. MySQL-строка становится 'Cannot touch this. Please avoid contractions.'

Поскольку User-B решил изменить строку MySQL до того, как пользователь-A завершил свою модификацию, сделанный модификацией User-A перезаписывается модификацией, сделанной User-B.

Как справляются с этим сценарии, которые позволяют одновременное редактирование строк базы данных (таких как MediaWiki или любое другое wiki-программное обеспечение)?

Ответы

Ответ 1

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

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

Что-то подобное происходит здесь, на SO. Если вы редактируете какой-либо вопрос, а кто-то еще сохраняет редактирование во время работы, вы получаете уведомление о том, что вопрос был изменен, а ваши изменения больше не действительны.

Ответ 2

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

Это также помогает, если вы используете переменную timestamp и sanity в форме, которая отправляет изменения отправки в вашу базу данных/обработку script. Затем вы можете проверить это на базе базы данных, прежде чем писать на нее, а если нет; дать пользователю сообщение о том, что есть сообщения или изменения до его/ее собственного... и пусть htem увидит это, прежде чем совершать свои собственные.

Ответ 3

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

Ответ 4

Мне понравился метод Уэсли Мерч. Также вы можете разрешить нескольким пользователям изменять один и тот же документ и использовать слияние, пока выполняется вторая фиксация. Перед редактированием вам нужно будет сохранить исходный документ.