Как предотвратить перезапись данных друг друга несколькими пользователями базы данных? - PullRequest
1 голос
/ 03 октября 2008

Если два пользователя обращаются к одной и той же таблице базы данных, как мы можем запретить пользователям перезаписывать данные друг друга?

Ответы [ 6 ]

2 голосов
/ 03 октября 2008

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

1 голос
/ 03 октября 2008

Некоторые серверы баз данных поддерживают конструкцию, подобную следующей:

SELECT column FROM table WHERE something = 'whatever' FOR UPDATE;

Блокирует все строки, возвращаемые селектором, до тех пор, пока не будут выполнены COMMIT или ROLLBACK.

MySQL (InnoDB) и Oracle - две базы данных, которые поддерживают это.

1 голос
/ 03 октября 2008

Ну, это зависит. Когда вы редактируете таблицу, это не то же самое, что открыть файл в MSWord или что-то в этом роде.

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

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

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

1 голос
/ 03 октября 2008

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

Возможно, у вас есть два варианта:

  • реализовать некоторый механизм блокировки на уровне приложения (то есть, когда кто-то начинает редактировать запись, где-то ставит флаг, который не позволит другому пользователю делать то же самое)
  • реализует управление версиями, поэтому каждый раз, когда кто-то пишет в базу данных, создается новая запись. Таким образом, оба набора данных будут находиться в базе данных, и вы можете иметь логику в своем приложении, чтобы объединить их или выбрать тот, который вам нравится
0 голосов
/ 03 октября 2008

Это большой вопрос без простого ответа. Это вызов сводится к тому, насколько вы готовы заблокировать одного пользователя, пока другой пользователь работает над ним, и как вы предотвращаете взаимные блокировки и паршивую производительность, когда это происходит. Кроме того, пытаетесь ли вы помешать одному пользователю обновить ту же строку, что и другой, или просто обновить другую строку в той же таблице? Если пользователь A обновляет строку, а затем пользователь B пытается обновить строку, должна ли она произойти сбой, обновить или молча проигнорировать ее? Как только вы определите проблему больше, вы сможете решить, нужны ли вам блокировки на уровне таблицы, блокировки на уровне строк, транзакции и нужны ли вам различные уровни изоляции транзакций.

0 голосов
/ 03 октября 2008

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

Используйте этот SQL для выполнения обновления.

UPDATE tab1
SET
    col1 = ?
    , col2 = ?
    , last_actv_dtm = GETDATE()
WHERE
    pkcol = rec.pkcol
    AND last_actv_dtm = rec.last_actv_dtm;

Это обновит строку, только если она не была изменена, так как приложение выбрало запись.

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