Я спрашиваю, как мне справляться с фоновыми потоками, выполняющими задачи, связанные с базой данных, в моем веб-приложении Hibernate / Spring.
В настоящее время я использую следующий перехватчик, поэтому я могу аннотировать методы запуска потока с помощью @OpenSession, и сессия должна быть открыта. Это также должно работать, например, для запросов RMI или любого другого метода, который вызывается без открытия сеанса. Однако я не уверен, что код правильный, но я сталкиваюсь с проблемой, что иногда сессии просто не закрываются и остаются открытыми навсегда.
@Around("@annotation(openSession)")
public Object processAround(ProceedingJoinPoint pjp, OpenSession openSession) throws Throwable {
boolean boundResource = false;
Session session = null;
// Bind the session to the thread, if not already done
if(TransactionSynchronizationManager.getResource(sessionFactory) == null) {
log.debug("Opening Hibernate Session in method "+pjp.getSignature());
session = SessionFactoryUtils.getSession(sessionFactory, true);
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
boundResource = true;
}
// Invoke the annotated method
Object ret;
try {
ret = pjp.proceed();
}
catch(Throwable t) {
// Rethrows the Exception but makes sure the session will be closed
SessionFactoryUtils.closeSession(session);
log.debug("Closing Hibernate Session in method (Exception thrown) "+pjp.getSignature());
throw t;
}
// If a resourc was bound by this method call, unbind it.
if(boundResource) {
//SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
session.flush();
SessionFactoryUtils.closeSession(session);
log.debug("Closing Hibernate Session in method "+pjp.getSignature());
}
return ret;
}