Оптимизированные для памяти таблицы SQL Server обнаруживают нарушение параллелизма

В оптимизированных для памяти таблицах SQL Server тип данных rowversion не разрешен.

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


person Kyle Reed    schedule 30.12.2017    source источник
comment
Как насчет использования собственного столбца идентификации для этой цели?   -  person Gordon Linoff    schedule 31.12.2017
comment
Расширьте предложение WHERE, чтобы все старые значения также передавались. Если обновление затрагивает 0 строк, эта строка должна быть изменена другим клиентом с момента загрузки вами старых значений.   -  person Caius Jard    schedule 31.12.2017


Ответы (2)


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

Когда вы загружаете строку в DataTable, dt отслеживает загруженные исходные значения:

SELECT id, name, age, address FROM person

--> 1, Jon, 33, null

Вы делаете обновление:

dt[0].Name = "Paul"

Строка теперь отслеживает два значения: исходное (Джон) и текущее (Пол).

Отправляя обновление обратно в базу данных, он выполняет такой запрос:

UPDATE person 
SET name = @currentName 
WHERE id = @originalID and 
 (Name = @originalName or (@originalName is null AND name is null)) AND 
 ...

Так эффективно:

UPDATE person 
SET name = 'Paul'
WHERE id = 1 and 
 (Name = 'John' or ('John' is null AND name is null)) AND...

Таким образом, данные, которые были изменены/обнулены/не обнулены внешним клиентом, могут быть обнаружены.

Может быть проще всего использовать ORM для вашего языка, который имеет эту возможность.

-

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

person Caius Jard    schedule 30.12.2017
comment
Альтернативой столбцу int является простой столбец datetime2, который записывает дату и время изменения (или создания) строки. Чуть больше полезной информации. - person SMor; 31.12.2017

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

Транзакции с Таблицы, оптимизированные для памяти

Код ошибки: 41302

Описание: Попытка обновить строку, которая была обновлена ​​в другой транзакции с момента начала текущей транзакции.

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

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

Например:

UPDATE
 [MyTable]
SET
 [Col001] = 'SomeVal'
WHERE
 PK = @primaryKey
 AND [RowVersionColumn] = @rowVersionStashedFromSelect
person Pittsburgh DBA    schedule 02.05.2018