Не удалось получить сеанс с синхронизацией транзакций для текущего потока при запуске получения сеанса гибернации из потока ScheduledExecutorService
Мне нужно создать механизм, чтобы продолжать тестировать состояние БД, если он жив или нет, для этого я попытался сделать следующее:
@Repository
@Transactional
public class DBServiceValidator implements ServiceValidator {
@Autowired
private SessionFactory sessionFactory;
private static final Logger logger = LogManager.getLogger(DBServiceValidator.class);
private transient boolean isValid = false;
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
private ScheduledFuture<?> scheduledFuture;
private long initialDelay;
private long interval;
@PostConstruct
public void init(){
initialDelay = 5;
interval = 5;
scheduleValidatePeriodicly(initialDelay, interval);
}
private void scheduleValidatePeriodicly(long initialDelay, long interval) {
logger.debug("Validate DB Service periodicly. initailDelay[{}], interval[{}]", initialDelay,
interval);
this.scheduledFuture = this.scheduler.scheduleAtFixedRate(runValidate(), initialDelay, interval,
TimeUnit.SECONDS);
}
private Runnable runValidate() {
return () -> {
validateDB();
};
}
@Override
public boolean isValid() throws BmaException {
return isValid;
}
@Transactional
private void validateDB(){
logger.debug("Going to validate DB Service");
try {
Session session = sessionFactory.getCurrentSession();
Integer result = (Integer) session.createSQLQuery("Select 1 from dual").uniqueResult();
if (result.intValue() == 1) {
isValid = true;
logger.trace("DB Service is valid");
}
isValid = false;
logger.error("DB Service is not valid, expected query result is 1, returned [[}]", result.intValue());
} catch (Exception exception) {
logger.error("DB Service is not valid", exception);
isValid = false;
}
}
@PreDestroy
public void destroy() {
logger.info("Going to destroy scheduler");
boolean isSchedulerCanceled = this.scheduledFuture.cancel(true);
this.scheduler.shutdown();
logger.debug("Scheduler destroyed. Is Canceled ? {}, is terminated ? {}", isSchedulerCanceled, this.scheduler.isTerminated());
}
}
и в XML-файле контекста приложения:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
</props>
</property>
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Это продолжает отбрасывать следующее исключение:
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134) ~[spring-orm-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
at com.att.bma.db.validator.BMADBServiceValidator.validateDB(BMADBServiceValidator.java:65) ~[bma-hibernate-db-al-4.0.0-SNAPSHOT.jar:?]
at com.att.bma.db.validator.BMADBServiceValidator.lambda$0(BMADBServiceValidator.java:53) ~[bma-hibernate-db-al-4.0.0-SNAPSHOT.jar:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_66]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [?:1.8.0_66]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_66]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [?:1.8.0_66]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_66]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_66]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_66]
Я пытался @Transactional
аннотации почти везде, о которых я думал, но это не решило проблему.
У кого-нибудь есть идеи?
Спасибо