Сессия гибернации в потоке с UserThread и сериализацией - PullRequest
0 голосов
/ 05 марта 2012

У меня есть следующий случай: У меня есть поток, который использует сеанс для сохранения или обновления

public void run()
{
    Session session = DAO.getInstance().getCurrentSession();
    Transaction tx = null;
        try
    {

        tx = session.beginTransaction();
        session.saveOrUpdate(entity);
             }catch.....
     }

Но в то же время во время сериализации с помощью session.saveorUpdate я изменяю объект сущности ... Таким образом, пользовательский поток будет изменять данные во время сериализации сеанса ..

Как мне преодолеть эту проблему? есть ли простой способ в спящем режиме?

EDIT: Самая большая проблема заключается в том, что UserThread изменяет некоторые данные в объекте сущности во время использования метода saveOrUpdate.

Ответы [ 2 ]

2 голосов
/ 06 марта 2012

Похоже, вам будет интересно оптимистическое управление параллелизмом с использованием управления версиями.

Оптимистическое управление параллелизмом

Если вы еще не сталкивались с этим, то аналогичную идею сравнитьand-swap, посредством которого Hibernate будет управлять версией вместе с сущностью.Увеличивая номер версии во время обновлений и проверяя, не изменился ли он после, Hibernate может обнаруживать конфликты и ошибки.Он оптимистично предполагает, что фактическая конкуренция встречается редко, и оставляет за разработчиком возможность обрабатывать исключения.Обычно я обнаружил, что это так, и, как говорят документы Hibernate,

Единственный подход, который согласуется с высоким параллелизмом и высокой масштабируемостью, - это оптимистичное управление параллелизмом с контролем версий.

Вы можете настроить видимость транзакций и уровень изоляции Hibernate, чтобы повлиять на более мелкие детали, см.

http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/transactions.html#transactions-optimistic

Разграничение транзакций

Я не могу сказатьиз фрагмента кода вопроса, но это также может стоить рассмотреть границы транзакции.Обычно я начинаю транзакцию (beginTransaction) в начале бизнес-операции или запроса, а также фиксирую и завершаю.Все обновления выполняются в этой модели сеанса (с одним Hibernate для одного потока на сеанс).Я все еще обрабатываю каждую бизнес-операцию или запрос в своем собственном потоке и полагаюсь на обычные уровни изоляции Hiernate и т. Д. Для управления конфликтами.

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

Если это не так, то, безусловно, стоит понять, возможны ли частые конфликты на производстве.Тестирование этого может помочь вам понять, действительно ли вам нужно беспокоиться об этом или вы можете полагаться на обычно управление транзакциями для обнаружения конфликтов и их обработки другими способами.

1 голос
/ 05 марта 2012

Одним из способов является синхронизация на объекте объекта:

public void run()
{
    Session session = DAO.getInstance().getCurrentSession();
    Transaction tx = null;
        try
    {

        tx = session.beginTransaction();
        synchronized(entity) {
            session.saveOrUpdate(entity);
        }
     }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...