Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Hibernate, доступ к базе с нескольких приложений 
:(
    Опции темы
pnd_ku
Дата 28.4.2009, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 25.9.2006

Репутация: нет
Всего: 1



Здраствуйте!

Мне нужно создать приложение на Java+Hibernate, но существует проблема:
может быть запущенно несколько инстансов этого приложения и тогда будет иметь место борьба за данные.
В моём случае - это книга назначений пациентов.
То есть 4 таблицы: врачи, пациенты, рабочие времена и назначения.

Как организовать data concurrency?

Спасибо!
PM MAIL   Вверх
garbuz
Дата 28.4.2009, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



Посмотрите паттерн синглтон.

PM MAIL   Вверх
tux
Дата 28.4.2009, 18:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Летатель
***


Профиль
Группа: Участник Клуба
Сообщений: 1853
Регистрация: 10.2.2005
Где: msk.ru

Репутация: 74
Всего: 132



Data concurrency можно организовать используя средства Hibernate. Например, он поддерживает версионность объектов, то есть умеет автоматически проставлять версии для сохраняемых объектов. Если сравнить версию редактируемого объекта с версией объекта, который сейчас в базе можно предпринять какие-то действия - загрузить данные из базы еще раз и попросить пользователя ввести заново или сделать еще что-то. В документации помнится все достаточно подробно было описано, примерно здесь - http://hibernate.org/hib_docs/v3/reference...ansactions.html. Сайт у них с сожалению сейчас не работает.

Это сообщение отредактировал(а) tux - 28.4.2009, 18:10
PM MAIL Skype GTalk Jabber YIM   Вверх
pnd_ku
Дата 28.4.2009, 19:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 25.9.2006

Репутация: нет
Всего: 1



to garbuz: одиночка в данной ситуации - не решение проблемы, а уход от неё

to tux: документация у них шыкааарная - тут не поспориш smile я подумывал о версионности тоже, похоже это наилучшее решение, спасибо вам, но возникает 2 вопроса

1) по теме. В документации к сожалению не описано как версионность регулируется. Да, там есть упоминание что это сделано таймстампами. Но версия объекта хранится в базе или в сессии?
Соответственно если версия отслеживается средставами БД, то вопрос решён.
Если же средствами хибернейт, то 2 разных хибернейт сессии не узнают о изменении версии объекта другой сессией.
Всё-таки в базе или в прослойке хибернейта?

2)чуть чуть не по теме. Флоу странности такой:
- выборка коллекции из базы по условиям... у нас появляется объект List, которые содержит выбранные сущности
- изменение одной из записей в базе непосредственно
- выборка коллекции по тем же условиям... по логам видно что запрос прошол, но свойства изменнённого объекта не обновились!

решение было такое - вызывать метод evict, чтобы сбросить кеш.. кажется мне - это странное решение, не элегантное..
почему же хибернейт не обновляет свойства изменённого объекта, ведь новые данные о нём он получил?
ах да, такая странность заметна только когда запрашиваю List, если делаю load одного объекта - всё в порядке


Поясню на примере логов хибернейта



Ожыдаем такое:

делаем запрос

Код

select this_.ID as ID2_0_, this_.therapiestId as therapie2_2_0_, this
_.dateTime as dateTime2_0_, this_.availableSlots as availabl4_2_0_, this_.commen
t as comment2_0_, this_.colorFG as colorFG2_0_, this_.colorBG as colorBG2_0_ fro
m doctor.AvailableSlots this_ where this_.therapiestId=? and this_.dateTime>=? a
nd this_.dateTime<? order by this_.dateTime asc


List availableSlots;

изменяем один из availableSlots не из текущей сессии

повторяем запрос

Код

select this_.ID as ID2_0_, this_.therapiestId as therapie2_2_0_, this
_.dateTime as dateTime2_0_, this_.availableSlots as availabl4_2_0_, this_.commen
t as comment2_0_, this_.colorFG as colorFG2_0_, this_.colorBG as colorBG2_0_ fro
m doctor.AvailableSlots this_ where this_.therapiestId=? and this_.dateTime>=? a
nd this_.dateTime<? order by this_.dateTime asc


List availableSlots должен содержать коллекцию с одним обновлённым слотом

но этого не происходит!!! 

Это сообщение отредактировал(а) pnd_ku - 28.4.2009, 19:30
PM MAIL   Вверх
garbuz
Дата 28.4.2009, 22:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



Цитата(pnd_ku @  28.4.2009,  14:46 Найти цитируемый пост)
может быть запущенно несколько инстансов этого приложения и тогда будет иметь место борьба за данные

Если несколько - это три, четыре, пять, то разве синглтона недостаточно?
PM MAIL   Вверх
pnd_ku
Дата 28.4.2009, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 25.9.2006

Репутация: нет
Всего: 1



Цитата(garbuz @ 28.4.2009,  22:15)
Цитата(pnd_ku @  28.4.2009,  14:46 Найти цитируемый пост)
может быть запущенно несколько инстансов этого приложения и тогда будет иметь место борьба за данные

Если несколько - это три, четыре, пять, то разве синглтона недостаточно?

4 разные машины, 4 запущщеных приложения с общими данными на сервере..
я что-то не очень понимаю при чом здесь синглтон
PM MAIL   Вверх
garbuz
Дата 28.4.2009, 22:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



Цитата(pnd_ku @  28.4.2009,  22:29 Найти цитируемый пост)
4 разные машины, 4 запущщеных приложения с общими данными на сервере..
я что-то не очень понимаю при чом здесь синглтон 


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

PM MAIL   Вверх
pnd_ku
Дата 28.4.2009, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 25.9.2006

Репутация: нет
Всего: 1



Общий сервер БД. И куча инстансов (все одинаковые) приложения. Все одинаковые. Всё таки клиент-сервер, но клиентов много. Почти всё верно!

Это сообщение отредактировал(а) pnd_ku - 28.4.2009, 23:29
PM MAIL   Вверх
tux
Дата 29.4.2009, 06:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Летатель
***


Профиль
Группа: Участник Клуба
Сообщений: 1853
Регистрация: 10.2.2005
Где: msk.ru

Репутация: 74
Всего: 132



Цитата(pnd_ku @  28.4.2009,  19:20 Найти цитируемый пост)
Всё-таки в базе или в прослойке хибернейта?

В базе. И это не обязательно timestamp, можно использовать тэг <version> и простой integer, который будет автоматически инкрементироваться при сохранении объекта. Например, вот такой простой класс и маппинг:
Код

public class Person {
    private Long id;
    private Integer version;

    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public Integer getVersion() {
        return version;
    }
    public void setVersion(Integer version) {
        this.version = version;
    }
}

Код

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping SYSTEM
    "http://hibernate.sourceforge.net/
    hibernate-mapping-3.0.dtd">

<hibernate-mapping package="my.package">

  <class name="Person" table="PERSON">

    <id name="id" column="ID"
        unsaved-value="null">
      <generator class="sequence">
        <param name="sequence">PERSON_SEQ</param>
      </generator>
    </id>

    <version name="version" column="VERSION" />
  </class>
</hibernate-mapping>

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

По пункту 2. По всей видимости ты данные в базе менял в момент активности сессии. Пока активна сессия, Hibernate кэширует все объекты, с которыми работает, поэтому и не подгружает объект. Загружать конкретные объекты тоже не должен, если конечно не пытаешься новый объект с тем же идентификатором создать. В принципе я понимаю почему у тебя проблемы - видимо сессия открывается один раз и потом не закрывается. Так делать не рекомендуется, обычно сессия открывается на один запрос. Вот надо тебе получить список слотов и показать на экране - открываешь сессию, загружаешь что нужно, показываешь и закрываешь сессию. Поведение Hibernate в этом случае вполне логично - что если пользователь захочет изменить один и тот же объект несколько раз? Не выполнять же столько же запросов к базе.

Это сообщение отредактировал(а) tux - 29.4.2009, 06:24
PM MAIL Skype GTalk Jabber YIM   Вверх
pnd_ku
Дата 29.4.2009, 06:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 25.9.2006

Репутация: нет
Всего: 1



1) вау! 2 переопределённых метода и изменения в маппинге - класс! в офф документации я этого не увидел, хотя прочитал всю в оригинале. великолепно! с хранением версии объекта в бд теперь всё исчерпывающе понятно, спасибо Вам огромное!

2)да, одна сессия на всё приложение. тут кстати в документации тоже конфликт. с одной стороны сессия-на-приложение - антипаттерн, но и с другой - сессия-на-запрос тоже. Тут дело такое, что мы отдетачели объект, а его оригинал в базе может быть изменён сторонним приложением и при апдейте его допустим нужно иметь свежайшую версию. Поэтому одна сессия на всё приложение. Хотя при некритичных ХиебрнейтЭксшепшнах все изменения откатываюца (в пределах одного ворк-юнита) и сессия пересоздаёца, чтобы избежать конфликтов и подгрузить заново все объекты.
Возможно Вы правы, и стоит рассмотреть вариант с сессией на запрос, но это чревато бОльшими расходами на работу с БД ибо выборка реально не маленькая и часто повторяющаяся.

А в целом Вы многое прояснили, премного благодарен! Теперь моя работа с хибернейтом станет ещё комфортнее  smile Грацыес! smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.1460 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.