2008-10-03 3 views
1

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

+0

Вы имеете в виду, что один пользователь не должен позволять редактировать данные другого пользователя? Или вы задаете вопрос о параллельности? Какую платформу базы данных вы используете? – 2008-10-03 15:04:39

+0

Какая база данных? Большинство из них имеют сложную блокировку, чтобы предотвратить это. Некоторые из них имеют относительно примитивную блокировку, что может помешать этому. – 2008-10-03 15:05:04

ответ

1

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

Два варианта вы, вероятно, есть следующие:

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

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

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

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

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

0

Самый гладкий подход, с которым я столкнулся, - это использовать дополнительное поле под названием 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; 

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

0

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

1

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

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

Который блокирует все строки, возвращаемые выбрать либо до COMMIT или ROLLBACK выпускаются.

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

Смежные вопросы