Безопасен ли поток сеанса Hibernate?

Мне нужно знать, является ли сеанс Hibernate потокобезопасным или нет. Но очевидно, что к каждому потоку для выполнения присоединяется новый сеанс. Но мой вопрос: если в одном потоке я обновил какое-то значение объекта, будет ли это отражено в другом потоке во время выполнения в то же время?

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

для например. текущий этап таблицы.

  ID      NAME      MARKS
------- --------- --------
  1       John       54

Я пытаюсь сделать следующее:

Student student = session.load(Student.class, 1);
student.setMarks(student.getMarks() + 1);
session.update(student);
session.close();

Когда я пытаюсь запустить приведенный выше код в цикле, скажем, 10, тогда значение «отметок» в таблице «студент» корректно обновляется, т. е. значение обновляется до 64, что является правильным.

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


person M.J.    schedule 23.09.2010    source источник


Ответы (4)


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

Даже с учетом этого ваше поведение может быть не таким, как вы ожидаете, потому что в игру вступают транзакции. Вам нужно будет установить правильный уровень изоляции транзакции. См. руководство по настройке, свойство hibernate.connection.isolation .

person Bozho    schedule 23.09.2010
comment
. Можете ли вы сказать мне, как достичь уровня изоляции в спящем режиме, добавив к вышесказанному, что я использую транзакцию для фиксации данных в базе данных. - person M.J.; 23.09.2010
comment
Этот JavaDoc упоминается, но не связан в документации Hibernate, на которую вы ссылались: docs.oracle.com/javase/8/docs/api/java/sql/Connection.html может помочь другим - person Jason Sperske; 01.12.2015

Сеанс гибернации и потоки не смешиваются.

Вы не должны использовать сеанс из нескольких потоков одновременно, и я рекомендую вам использовать сеанс только из одного потока. Реализации сеанса БД даже не обязаны быть безопасными для рекламы.

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

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

person Peter Tillemans    schedule 23.09.2010

Сеансы Hibernate не являются потокобезопасными. Используйте класс TheadLocal для создания сеансов для каждого потока: -

 private static ThreadLocal<Session> threadSafeSession = new ThreadLocal<Session>() {
    protected Session initialValue(){
    return sf.openSession();
      }
    };

В вашем методе получите сеанс для каждого потока как: -

Session session = threadSafeSession.get();
person Goyal Vicky    schedule 09.08.2015

Это зависит от того, как вы создаете сеанс.

Сессия может быть создана двумя способами в спящем режиме.

  1. получить текущий сеанс ()

Да. Он обеспечивает безопасность потоков, поскольку гарантирует создание сеанса для каждого потока, если сеанс не существует. к этому прилагается транзакция и автоматическое закрытие сеанса.

  1. открытьсессию()

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

person Sumanth Varada    schedule 11.03.2017