У меня есть приложение PHP / jQuery / AJAX / MySQL, созданное для управления базами данных. Я хочу реализовать возможность предотвращения одновременного редактирования одной и той же строки базы данных несколькими пользователями.
Я просто не уверен, что лучше. Предполагая, что между 10 – 15 одновременными пользователями
Существует два общих подхода – оптимистическая и пессимистическая блокировка.
Оптимистичную блокировку, как правило, намного проще реализовать в веб-среде, поскольку она принципиально без гражданства. Он также намного лучше. Недостатком является то, что предполагается, что ваши пользователи обычно не будут пытаться редактировать один и тот же набор строк одновременно. Для большинства приложений это очень разумное предположение, но вы должны убедиться, что ваше приложение не является одним из факторов, когда пользователи будут регулярно наступать друг на друга. В оптимистичной блокировке у вас будет какой-то столбец last_modified_timestamp
который вы бы last_modified_timestamp
, когда пользователь извлекал данные, а затем использовал в WHERE
при переходе к обновлению даты, т. Е.
UPDATE table_name SET col1 = <<new value>>, col2 = <<new values>>, last_modified_timestamp = <<new timestamp>> WHERE primary_key = <<key column>> AND last_modified_timestamp = <<last modified timestamp you originally queried>>
Если это обновляет 1 строку, вы знаете, что вы были успешны. В противном случае, если он обновляет 0 строк, вы знаете, что кто-то еще модифицировал данные в промежутке времени, и вы можете предпринять некоторые действия (обычно показываете пользователю новые данные и спрашиваете их, хотят ли они перезаписать, но вы можете использовать другие подходы к разрешению конфликтов ).
Пессимистическая блокировка более сложна для реализации, особенно в веб-приложении, особенно когда пользователи могут закрыть свой браузер без выхода из системы или когда пользователи могут начать редактировать некоторые данные и пойти на обед перед тем, как нажать « Submit
. Это усложняет масштабирование и, как правило, затрудняет администрирование приложения. На самом деле стоит только подумать, будут ли пользователи регулярно пытаться обновлять одни и те же строки или если обновление строки занимает много времени для пользователя, поэтому стоит сообщить им, что кто-то другой заблокировал строку.
Я собирался реализовать это в одной из своих систем.
Вы можете создавать новые столбцы в своей базе данных записей, называемых timelocked.
Когда запись открыта, вы должны установить столбец записи, который они открывают, для того, чтобы пометить это время. Во время редактирования записи отправляйте keepalive обратно на сервер через ajax каждые 2 минуты. При отправке keepalive сервер будет увеличивать время с таймером до текущего времени отправки запроса и, следовательно, четвертого (это будет иметь смысл в секунду). Когда пользователь закончит редактирование, установите timelocked в false.
Теперь, если кто-то пошел открывать запись, которая уже открыта, php проверит – если timelocked == false – будет означать, что он не редактируется,
в противном случае запись может редактироваться, но что, если пользователь закрыл окно своего браузера. поэтому используется keepalive.
если разница между текущим временем и таймером больше 2 минут, это означает, что они больше не ожидают редактирования, что позволит вам открыть его.
Надеюсь, вы все это понимаете.
Не пытайтесь предотвратить это. Пусть они решат, что делать в случае конфликта изменений.
Добавьте временную метку в таблицу. Сравните временную метку, когда строка была восстановлена с текущей меткой времени. Сообщите им об изменениях между их нагрузкой и их сохранением и дайте им понять, какие действия нужно предпринять.
Так да, номер 3.
Я лично не помешал бы этому. Если бы это было требование задания, я бы отслеживал текущее / последнее известное местоположение пользователей и запретил кому-то редактировать одну и ту же строку, которую кто-то редактирует таким образом. Я видел, как люди добавляли строку в таблицу, говорящую isLocked или isBeingWorkedOn и т. Д., Но я видел, что этот тип системы терпит неудачу намного чаще, или требуют модерации, чтобы разблокировать застрявшие таблицы, если кто-то закрыл ее во время работы над ней и т. Д. ..
1) Это называется блокировкой. Существует два основных типа блокировки при обращении к реляционным базам данных (например, MySQL): блокировка таблицы и блокировка строк. Блокировка таблицы гарантирует, что только один сеанс в момент внесет изменения в таблицу, тогда как блокировка строк гарантирует, что только один сеанс за один раз вносит изменения в определенную строку. Вы можете думать о блокировке строк как более тонком подходе к параллельному доступу, чем блокировка таблицы. Блокировка строк сложнее, но позволяет нескольким параллельным сеансам писать в одну и ту же таблицу (важно, если в вашей базе данных много параллельных записей – блокировка таблицы должна быть хорошей для 10-15 пользователей)
2-3) MySQL заботится о параллельном доступе для вас! Он автоматически реализует блокировку в фоновом режиме. Тип блокировки (строка или таблица) зависит от используемого вами механизма хранения. Например, MyISAM использует блокировку таблиц, а InnoDB использует блокировку строк. Для управления MySQL используется внутренняя таблица. Вы можете запросить статус этой таблицы (и всех блокировок в своей базе данных), проверив переменные Table_locks_immediate
и Table_locks_waited
(она использует ваш вариант номер 2).
Когда вы выдаете инструкцию INSERT или UPDATE, когда другой сеанс использует таблицу (или строку), вызывающее приложение (то есть PHP в этом случае) приостанавливается на несколько миллисекунд, пока другой сеанс не будет выполнен.
4) Опять же, MySQL автоматически позаботится о блокировке, но вы можете вручную управлять блокировкой таблицы с помощью команд LOCK TABLES
и UNLOCK TABLES
. Если вы используете блокировку строк с помощью InnoDB, существует множество функций, которые можно использовать для ручного управления одновременным доступом.
См. Страницу MySQL по внутренней блокировке для обзора системы блокировки MySQL и параллельных вставок для функций блокировки строк InnoDB.
Как говорили другие, гораздо легче справиться с противоречивым обновлением. То, что вы предлагаете, называется пезимистической блокировкой. Это называется thate, потому что слишком вероятно, что два пользователя будут пытаться редактировать одну и ту же запись одновременно.
Это правда?
И это катастрофа, если пользователь должен начать снова, потому что данные, которые они пытались обновить, были изменены кем-то другим.
Затраты на блокировку, вы всегда блокируете пессимистическую схему, поэтому у вас есть накладные расходы, и это до того, как вы начнете смотреть на связанные данные и т. Д.
Сделать это надежным, имея дело с тем, что никто не может это сделать, теперь coz sumfin 'пошло не так …
Если бы у меня было что-то, кроме редактирования целого файла, для которого требовалась пессимистическая блокировка, я бы посмотрел на мой дизайн, исходя из того, что он не подходит для цели.