Как я могу установить таймаут для вызова save () Hibernate с бэкэндом MySQL? - PullRequest
7 голосов
/ 16 августа 2011

На прошлой неделе мы столкнулись с проблемой в большой системе на основе Hibernate на Java.Наша внутренняя база данных MySQL (размещенная на Amazon RDS) не отвечала на запросы в течение 5-10 минут (она по-прежнему принимала соединения, но из-за проблем с оборудованием пропускная способность записи упала до нуля).Этот кусок кода:

getSession().save(entity); //session is an instance of org.hibernate.Session

Зависает до 8,5 минут.Очевидно, что в этом утверждении необходимо какое-то условие тайм-аута, чтобы оно не сработало в случае моего конкретного сценария.Я не могу гарантировать, что в будущем подобной проблемы с оборудованием я не увижу.

Я должен отметить, что я все еще довольно плохо знаком с Hibernate, поэтому возможно, что я просто не понимаю некоторые вещинапример, связь между использованием save() и критериями, транзакциями и т. д. Итак, я обнаружил следующее:

  • hibernate.c3p0.timeout можно использовать для установки тайм-аутов соединения в пуле соединений C3P0
  • getSession().getTransaction().setTimeout(...) может использоваться для тайм-аута транзакции
  • getSession().createQuery(...).setTimeout(...) может использоваться для тайм-аута запроса
  • Я видел JPA 2 javax.persistence.query.timeout, но я 'я не совсем уверен, что это то, что я хочу (я также не думаю, что моя версия Hibernate достаточно новая)

Ничто из этого не похоже на то, что я хочу сделать (кроме, может быть, JPA 2),Кажется, это должно быть очень просто.Я что-то здесь упускаю?

Спасибо!

Ответы [ 3 ]

6 голосов
/ 16 августа 2011

Я уже искал подобные вещи раньше, но использовал Oracle на бэкэнде вместо MySQL. Насколько я когда-либо видел, просто нет никакого механизма для этого в любой библиотеке, включая драйверы JDBC. Даже указанные вами тайм-ауты, такие как Transaction.setTimeout (), не соответствуют ожидаемым. Они просто ждут завершения выполнения оператора базы данных, и , а затем выдают исключение TimeoutException, если оно превысило заданное время ожидания. Это довольно бесполезно, если у вас есть запрос, который просто висит бесконечно. Единственное потенциальное готовое решение, которое я когда-либо нашел, - это установить тайм-аут запроса для самой базы данных, который в Oracle является глобальным параметром и повлияет на все запросы к базе данных. Это не очень полезно. Насколько я могу судить, чтобы сделать то, что вы ищете, вам нужно было бы запустить отдельный поток, чтобы синхронизировать запросы по мере их выполнения и каким-то образом прерывать их, когда они достигают тайм-аута. Я не нашел никакой поддержки для этого ни в Oracle, ни в каких-либо связанных с БД библиотеках / инфраструктурах.

0 голосов
/ 16 августа 2011

Если проблема связана с отзывчивостью внешнего интерфейса, вы можете рассмотреть возможность асинхронного выполнения обращений к БД любым удобным для вас способом.Тогда вы не обязаны своевременности бэкэнда.Вы можете использовать мост JMS, или, если вы находитесь в Spring, вы можете использовать @Async, или что-нибудь еще, что асинхронно.

Если вы выполняли EJB, вы можете установить тайм-аут транзакции для контейнераили, если вы используете BMT, на самой транзакции.Этот параметр завершит передачу по истечении времени ожидания.

В качестве альтернативы, вы также можете просто переместить вашу БД локально.

0 голосов
/ 16 августа 2011
  • hibernate.c3p0.timeout ex: 300 Вы указываете период ожидания (в данном случае 300 секунд), после которого простое соединение удаляется из пула).hibernate.c3p0.idle_test_periods Это время простоя в секундах до автоматической проверки соединения.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...