Распределяет ли beginTransaction в Hibernate новое соединение с БД? - PullRequest
13 голосов
/ 29 марта 2010

Просто интересно, если начало новой транзакции в Hibernate фактически выделяет соединение с БД?

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

Искал везде и не смог найти хорошего ответа. Очень простой код здесь:

    SessionFactory sessionFactory = (SessionFactory) Context.getContext().getBean("sessionFactory");
    sessionFactory.getCurrentSession().beginTransaction();
    sessionFactory.getCurrentSession().setFlushMode(FlushMode.AUTO);

спасибо большое! а

Ответы [ 2 ]

16 голосов
/ 31 марта 2010

По разделу 11.1. Области сеансов и транзакций документации Hibernate:

A SessionFactory является дорогой в создании, потокобезопасный объект, предназначенный для совместного использования всеми темы приложений. Создан один раз, обычно при запуске приложения, из экземпляра Configuration.

А Session - это недорого, не потокобезопасный объект, который должен быть используется один раз, а затем отбрасывается для: одиночный запрос, разговор или единица работы. A Session будет не получить JDBC Connection или Datasource, если это не нужно. Это не будет потреблять никаких ресурсов, пока б.

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

Теперь, чтобы ответить на ваш вопрос:

  • получение Session делает не немедленным установлением соединения (соединение загружено с отложенным доступом)
  • но вызов beginTransaction() вызовет загрузку соединения для данного Session
  • последующие вызовы будут использовать то же самое connection

Посмотрите на org.hibernate.impl.SessionImpl#beginTransaction() и просмотрите код для получения более подробной информации.

8 голосов
/ 29 марта 2010

(Обновлено за комментарий Паскаля Тивента)

Каждый Session создает соединение с базой данных, если в этом есть необходимость - например, если транзакция запущена. Соединение не открывается простым созданием сеанса.

Чтобы преодолеть это, вы можете использовать пул соединений , чтобы соединения использовались повторно. Или вы можете убедиться (как вы это сделали), что ни одна транзакция не запускается автоматически.

( В этом рассматриваются транзакции только для чтения. Посмотрите.)

...