Я использую Open Session-In-View-модель транзакций для моего REST API, как это:@Async убивает Hibernate транзакции
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
sessionFactory.getCurrentSession().beginTransaction();
chain.doFilter(request, response);
sessionFactory.getCurrentSession().getTransaction().commit();
}
Эта работа просто отлично. Я хотел добавить способности @Async. Так что я создал:
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
@Override
@Bean(destroyMethod="shutdown")
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(18);
executor.setMaxPoolSize(18);
executor.initialize();
executor.setDaemon(true);
executor.setWaitForTasksToCompleteOnShutdown(false);
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SimpleAsyncUncaughtExceptionHandler();
}
}
и:
@Component
public class AsyncMarketCaller {
@Inject
MarketManagerFactory marketManagerFactory;
@Async
public Future<List<Product>> getProducts(){
MarketManager productManager = marketManagerFactory.obtainMarketManager(market);
result = productManager.getProducts();
....
}
}
делает менеджер по продукту вызова другого @Service
@Service
public class DefaultIdentifierManager implements IdentifierManager{
@Inject
UpcEanDAO upcEanDAO;
@Override
public String getTitleForIdentifier(String identifier){
UpcEan upcEan = upcEanDAO.find(identifier);
}
}
Однако для upcEanDAO.find(identifier)
я получаю исключение:
Caused by: org.hibernate.HibernateException: get is not valid without active transaction
До I добавил @Async
возможность совершать асинхронные вызовы до getProducts()
, он работал нормально, поэтому я предполагаю, что @Async
убивает транзакцию, которую я открыл с помощью Hibernate.
Я попытался добавить на основании другого ответа здесь, @Transactional
к методу, аннотированному с @Async
, но это не поможет.
Есть идеи?
EDITED
Я редактировал код так
@Component
public class AsyncMarketCaller {
@Inject
AsyncMarketService asyncMarketService;
@Async
public Future<List<Product>> getProducts(){
asyncMarketService.getProducts();
}
}
и
@Service
public class AsyncMarketService {
@Inject
MarketManagerFactory marketManagerFactory;
@Transactional
public Future<List<Product>> getProducts()
....
}
}
Я вижу в журнале
50689 DEBUG [localhost-startStop-1] org.springframework.transaction.annotation.AnnotationTransactionAttributeSource - Adding transactional method 'AsyncMarketService.getProducts' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
но это не помогает. Обратите внимание, что мой метод AsyncMarketService.getProducts не вызывает непосредственно БД, он вызывает другие методы, и только один из них сделает вызов.
Я также добавил выше того, что на самом деле сделать вызов к БД: @Transactional
49992 DEBUG [localhost-startStop-1] org.springframework.transaction.annotation.AnnotationTransactionAttributeSource - Adding transactional method 'DefaultIdentifierManager.getTitleForIdentifier' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '
'
Поскольку ваша транзакция поручена через фильтр, не может быть сделкой на месте, когда вам это нужно. – Hannes
@ Ханнес - он работал до того, как я добавил Async - который является частью вызова фильтра – Dejell