Потерянные обновления в Ms SQL Server
От: Быдлокодер  
Дата: 04.10.10 20:54
Оценка:
Практического опыта работы с БД к сожалению нет. Из курса СУБД помню, что проблема вроде бы классическая, но вот классического решения не припоминаю. Да и в гугле ничего толкового найти не удалось как ни странно.

Опишу проблему на примере: двум пользователям отправлена страничка с одинаковыми данными. Один изменил ее и быстро отправил на сервер. А другой только через пол часа. Но вот беда, меня то он ее на основе устаревших данных и не видел, что ввел другой пользователь, данные которого потерялись.

Кто может посоветовать решение?

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

Приемлемое ли такое решение?
Re: Потерянные обновления в Ms SQL Server
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 04.10.10 21:07
Оценка: +1
Здравствуйте, Быдлокодер, Вы писали:

Б>Опишу проблему на примере: двум пользователям отправлена страничка с одинаковыми данными. Один изменил ее и быстро отправил на сервер. А другой только через пол часа. Но вот беда, меня то он ее на основе устаревших данных и не видел, что ввел другой пользователь, данные которого потерялись.


Б>На вскидку думаю в хранимую процедуру обновления данных передавать старое значение и если оно совпадает с текущим, то производить обновление, если нет, то посылать пользователю сообщение обновить страницу, т.к. его данные устарели.


Б>Приемлемое ли такое решение?


Да. Optimistic concurrency называется
Re[2]: Потерянные обновления в Ms SQL Server
От: Быдлокодер  
Дата: 04.10.10 21:15
Оценка:
gandjustas, спасибо! По вашему ключу как раз нашел видимо то, что нужно http://msdn.microsoft.com/ru-ru/library/aa0416cz.aspx
Re: Потерянные обновления в Ms SQL Server
От: Lloyd Россия  
Дата: 04.10.10 21:31
Оценка:
Здравствуйте, Быдлокодер, Вы писали:

Б>Кто может посоветовать решение?


Б>На вскидку думаю в хранимую процедуру обновления данных передавать старое значение и если оно совпадает с текущим, то производить обновление, если нет, то посылать пользователю сообщение обновить страницу, т.к. его данные устарели.


Б>Приемлемое ли такое решение?


Можно и так, но лучше все-таки использовать для этого timestamp-ы.
Re: Потерянные обновления в Ms SQL Server
От: MasterZiv СССР  
Дата: 05.10.10 08:43
Оценка:
Быдлокодер wrote:
> Практического опыта работы с БД к сожалению нет. Из курса СУБД помню,
> что проблема вроде бы классическая, но вот классического решения не
> припоминаю. Да и в гугле ничего толкового найти не удалось как ни странно.

Ну да, lost update называется Он же write scqueue. Но это не совсем он, а похожая
ситуация. lost update -- это феномен (один из), в терминах которого
описываются уровни изоляции транзакций.

> Опишу проблему на примере: двум пользователям отправлена страничка с

> одинаковыми данными. Один изменил ее и быстро отправил на сервер. А
> другой только через пол часа. Но вот беда, меня то он ее на основе
> устаревших данных и не видел, что ввел другой пользователь, данные
> которого потерялись.
>
> Кто может посоветовать решение?
>

Решения два.
1) делать всё, начиная с чтения данных,
включая редактирование и сохранение в одной большой долгой
транзакции. Тогда сама СУБД сможет обнаружить конфликт и
разрешить ситуацию. Ситуация будет разрешена ОТМЕНОЙ и откатом
одной из транзакций. Проблема только в том, что транзакции
будут долгими и должны они проходить на высоком уровне
сериализации (видимо, SERIALIZABLE).

2) Использовать так называемый optimistic lock.
Заключается он в том, что ничего не блокируется, всё
в отдельных транзакциях, но при сохранении данных проверяется,
что никто до тебя данные не поменял. Это можно сделать несколькими
путями
-- по совпадению всех полей данных.
пишется
update theTable set .... where pk = @pk and field1 = @field1 and field2 =
@field2
и так далее, все поля записи (кроме PK,который и так уже есть).
@field1, @field2 ... -- естественно, изначально прочитанные из СУБД значения
полей, до изменения.
-- по полю типа timetsamp.
Аналогично предыдущему, но изменение записи контролируется только по
значению одного поля типа timetsamp. Напоминаю, что такое поле может быть
в записи только одно и оно автоматом меняется сервером при изменении записи.
(а руками его поменять нельзя)
-- комбинация первого и второго.
При обнаружении конфликта -- UPDATE при этом не изменит ни одной записи --
запись читается с сервера снова, и пользователь её должен редактировать
заново (изменения теряются).

Преимущества -- нет длинной транзакции, нет конфликтов. Недостатки --
более сложная схема сохранения данных.

> На вскидку думаю в хранимую процедуру обновления данных передавать

> старое значение и если оно совпадает с текущим, то производить
> обновление, если нет, то посылать пользователю сообщение обновить
> страницу, т.к. его данные устарели.

Ну, ты знал, ты знал.
Posted via RSDN NNTP Server 2.1 beta
Re[2]: Потерянные обновления в Ms SQL Server
От: avpavlov  
Дата: 05.10.10 08:51
Оценка:
MZ>2) Использовать так называемый optimistic lock.
MZ>Заключается он в том, что ничего не блокируется, всё
MZ>в отдельных транзакциях, но при сохранении данных проверяется,
MZ>что никто до тебя данные не поменял. Это можно сделать несколькими
MZ>путями
MZ> -- по совпадению всех полей данных.
MZ> пишется
MZ> update theTable set .... where pk = @pk and field1 = @field1 and field2 =
MZ>@field2
MZ> и так далее, все поля записи (кроме PK,который и так уже есть).
MZ> @field1, @field2 ... -- естественно, изначально прочитанные из СУБД значения
MZ>полей, до изменения.
MZ> -- по полю типа timetsamp.
MZ> Аналогично предыдущему, но изменение записи контролируется только по
MZ>значению одного поля типа timetsamp. Напоминаю, что такое поле может быть
MZ>в записи только одно и оно автоматом меняется сервером при изменении записи.

Всё верно, только со сравнением всех полей я бы связываться не стал. Потому что есть НУЛЛы, есть блобы — всё это требует специальной обработки, так что решение с таймстампом идеальное. А где нет таймстампа, там легко свой счётчик приделать.

update ... set .... , [version]=@v+1 where pk=@pk and [version] = @v
Re[3]: Потерянные обновления в Ms SQL Server
От: MasterZiv СССР  
Дата: 05.10.10 10:22
Оценка:
avpavlov wrote:

> Всё верно, только со сравнением всех полей я бы связываться не стал.

> Потому что есть НУЛЛы, есть блобы — всё это требует специальной
> обработки, так что решение с таймстампом идеальное. А где нет
> таймстампа, там легко свой счётчик приделать.

Я бы тоже не стал.
Posted via RSDN NNTP Server 2.1 beta
Re: Потерянные обновления в Ms SQL Server
От: Быдлокодер  
Дата: 10.10.10 16:35
Оценка:
Спасибо всем за участие. Особенно благодарю MasterZiv за развернутый ответ.

Тему переименовали и я просто не увидел новых сообщений

Использую rowversion, т.к. пишут, что timestamp не будет поддерживаться в будущих версиях.

http://technet.microsoft.com/ru-ru/library/ms182776(SQL.90).aspx
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.