Как предположил Спенс, вам нужен оптимистичный параллелизм.Стандартный веб-сайт, который не учитывает, изменились ли данные, использует то, что я называю «последние записи выигрывают».Проще говоря, независимо от того, какое соединение сохраняется в базе данных последним, эта версия данных остается неизменной.В оптимистическом параллелизме вы используете логику «первая запись выигрывает», так что если два соединения пытаются сохранить одну и ту же строку одновременно, первое, которое фиксирует выигрыш, а второе отклоняется.
Этот механизм состоит из двух частей:
- Правила, по которым вы не выполняете второй коммит
- Как система или пользователь обрабатывают отклоненный коммит.
Определение отклонения фиксации
Два подхода:
- Столбец сравнения, который изменяется каждый раз, когда происходит фиксация
- Сравнить данныес его подтвержденной версией в базе данных.
Первый предполагает использование чего-то вроде типа данных SQL Server rowversion
, который гарантированно будет меняться при каждом изменении строки.Положительным моментом является то, что это упрощает использование собственной логики, чтобы определить, изменилось ли что-то.Когда вы получаете данные, вы извлекаете значение столбца rowversion
, а при фиксации сравниваете это значение с тем, что в данный момент находится в базе данных.Если они отличаются, данные изменились с момента вашего последнего получения, и вам следует отклонить фиксацию, в противном случае перейдите к сохранению данных.
Второй - сравнение столбцов, которые вы извлекли, с их существующими значениями фиксации в базе данных.,Как предположил Спенс, если вы попытаетесь обновить и ни одна строка не будет обновлена, то очевидно, что один из критериев не выполнен.Эта логика может стать хитрой, когда некоторые значения равны нулю.Многие объектно-реляционные сопоставители и даже технологии .NET DataTable и DataAdapter могут помочь вам справиться с этим.
Обработка отклоненного коммита
Если вы не оставите это на усмотрение пользователя, то форма выдасткакое-то сообщение о том, что данные изменились с момента последнего редактирования, и вы просто восстановите данные, перезаписав их изменения.Как вы можете себе представить, пользователи не особенно любят это решение, особенно в системах с большим объемом, где это может происходить часто.
Более сложный (и также более сложный) подход состоит в том, чтобы показать пользователю, что изменилось, и позволить ему выбрать, какие элементы попытаться повторно зафиксировать. За кулисами вы снова получите данные, перезапишите значениявыбирается пользователем со своими записями и пытается зафиксировать снова.В системах с большими объемами это все еще будет проблематично, потому что к тому времени, когда пользователь попытается выполнить повторную фиксацию, данные могут снова измениться.
Концепция извлечения - это эффективно пессимистичный параллелизм, когда пользователи "блокируют" строки.Как вы обнаружили, это трудно реализовать в среде без состояния.Пользователи печально известны тем, что просто закрывают свой браузер, когда они что-то извлекли, или используют кнопку «Назад», чтобы вернуть проверенный набор и попытаться повторить его.ИМО, это больше проблем, чем стоит пытаться пойти по этому пути в веб-решении.Предполагая, что вы пишете имя пользователя, которое в последний раз изменило данную строку, с оптимистичным параллелизмом, вы можете сообщить пользователю, отклоненные изменения которого сохранили данные перед ними.