Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Конкурентный update и JPA


Автор: batigoal 2.4.2008, 19:46
Всем привет,

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

1) Юзер 1 открывает запись на редактирование и меняет её (для усложнения задачи допустим, что речь идет о десктоп-клиенте)
2) Юзер 2 открывает ту же запись на редактирование
3) Юзер 1 нажимает "сохранить". Запись сохраняется в базу.
4) Юзер 2 нажимает "сохранить". Запись сохраняется в базу, перетирая изменения от юзера 1.

Как решать такую проблему? Я надеялся, что JPA имеет такой механизм, но, похоже, был не прав.

Вообще, проблема эта популярная, поэтому наверняка существуют и паттерны её решения, и библиотеки с подобными возможностями. Помогите советом или ссылками.

Мои соображения: 

1) сейчас у нас за разрешение подобных конфликтов отвечает механизм stamp'ов, т.е. каждая запись имеет номер, инкрементально увеличивающийся при апдейте. Если юзер 2 хочет проапдейтить запись, но видит, что её stamp поменялся со времени загрузки, он возвращает ошибку. Но с обязанностями своими наш фреймворк справляется плохо - нетривиальные случаи использования типа кеширования или иерархической зависимости объектов (когда изменение стемпа одного объекта вызывает изменение стемпа другого) вызывают множественные side-эффекты. Хотя дело тут, во многом, в кривой реализации, а не в порочности идеи стемпов, всё таки не хочется изобретать велосипед, если он уже кем-то изобретен.
2) Другой подход - лочить запись на уровне базы, когда отдаем её кому-то на редактирование (SELECT FOR UPDATE). Но в таком случае оператор, оставивший запись залоченной перед уходом на обед, блокирует работу остальных (Stampede в свое время называл это "проблемой ковыряния в носу").

Автор: w1nd 3.4.2008, 07:23
Цитата(batigoal @  2.4.2008,  19:46 Найти цитируемый пост)
сейчас у нас за разрешение подобных конфликтов отвечает механизм stamp'ов, т.е. каждая запись имеет номер, инкрементально увеличивающийся при апдейте. Если юзер 2 хочет проапдейтить запись, но видит, что её stamp поменялся со времени загрузки, он возвращает ошибку.

Так же. Руками.

Автор: kkorsakoff 3.4.2008, 12:04
Так Hibernate вроде бы умеет? Version в хмл конфигурации. Насколько я знаю в JPA при использовании Hibernate в качестве провайдера можно использовать все его фичи. Честно говоря не пробовал, но в документации бегло читал про это. 

Автор: mindflyer 3.4.2008, 12:15
Используем версионность хибернейта - по сути те самые stamp'ы и есть. Жалоб не имеем smile

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

Автор: batigoal 3.4.2008, 16:50
Заценим-с, спасибо.

Автор: Asal 21.8.2008, 13:24
batigoal, поделитесь успехами.
Что-нибудь получилось ?

Автор: powerOn 21.8.2008, 14:26
Ищите книгу Мартина Фаулера "Архитектура корпоративных программных приложений". Там целая глава посвещена блокировкам. 

http://martinfowler.com/eaaCatalog/optimisticOfflineLock.html
http://martinfowler.com/eaaCatalog/pessimisticOfflineLock.html
http://martinfowler.com/eaaCatalog/coarseGrainedLock.html
http://martinfowler.com/eaaCatalog/implicitLock.html

Автор: alexadr 21.8.2008, 14:33
Цитата(batigoal @  2.4.2008,  19:46 Найти цитируемый пост)
Я надеялся, что JPA имеет такой механизм, но, похоже, был не прав.

Оно в жпа есть:
javax.persistence.Version

Автор: Asal 21.8.2008, 15:13
Цитата(powerOn @  21.8.2008,  14:26 Найти цитируемый пост)
Ищите книгу Мартина Фаулера "Архитектура корпоративных программных приложений".

Нашел. книга http://depositfiles.com/ru/files/2729004.

powerOn, спасибо за совет, буду читать.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)