【发布时间】:2015-08-27 16:32:13
【问题描述】:
我知道之前有人问过这个问题,但是没有一个解决方案对我有用。
我正在尝试使用控制器来填充索引。当我尝试在数据库中搜索更新时会出现问题。
这是我正在处理的类:
配置:
@Configuration
@EnableTransactionManagement
public class WebApplication implements WebApplicationContextInitializer, ApplicationContextAware {
@Bean(name="dataSource")
public DataSource getDataSource() throws IOException {
InitialContext initialContext = new Context();
return (DataSource) initialContext.lookup("java:comp/env/jdbc/myDataSource");
}
@Bean(name="sessionFactory")
public SessionFactory getSessionFactory() throws IOException {
LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(getDataSource());
sessionBuilder.scanPackages(PropertyUtil.getInstance().getPropertySplitTrimmed("hibernate", "packagesToScan"));
sessionBuilder.addProperties(PropertyUtil.getInstance().getProperties("hibernate"));
return sessionBuilder.buildSessionFactory();
}
@Bean(name="transactionManager")
public HibernateTransactionManager transactionManager() throws IOException {
return new HibernateTransactionManager(getSessionFactory());
}
}
控制器:
@RestController
@Transactional
@RequestMapping("/persons")
public class IndexController {
@Autowired
PersonsDao personsDoa;
private ExecutorService executorService = Executors.newFixedThreadPool(100);
@RequestMapping(value="/index")
public void populateIndex(@DefaultValue("") @RequestParam String name){
...
...
List<Future<Persons>> holder = new ArrayList<>();
for(Persons p : people){
String name = p.name();
Future<Person> f = this.executorService.submit(new Callable<Person>(){
@Override
public Person call() throws Exception {
return personsDao.findByName(name); // <-- Throws error here
}
});
holder.add(f); // process the array later once all threads are finished
}
...
...
}
}
更新:我根据一些建议更新了我的控制器,但是我仍然收到同样的错误
控制器:
@RestController
@Transactional
@RequestMapping("/persons")
public class IndexController {
@Autowired
PersonsDao personsDoa;
private ExecutorService executorService = Executors.newFixedThreadPool(100);
@RequestMapping(value="/index")
public void populateIndex(@DefaultValue("") @RequestParam String name){
...
...
List<Future<Persons>> holder = new ArrayList<>();
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(sessionFactory.getCurrentSession())); //<-- THROWS ERROR HERE
for(Persons p : people){
String name = p.name();
Future<Person> f = this.executorService.submit(new Callable<Person>(){
SessionHolder holder = (SessionHolder)TransactionSynchronizationManager.getResources(sessionFactory);
Session session = holder.getSession();
@Override
public Person call() throws Exception {
Transaction t = session.getTransaction();
t.begin();
Persons p = personsDao.findByName(name);
t.commit();
session.flush();
return p;
}
});
holder.add(f); // process the array later once all threads are finished
}
...
...
}
}
【问题讨论】:
-
您是否尝试将
@Transactional注释放在PersonsDao中的方法findByName(String name)上方? -
是的。我尝试手动删除注释并管理事务,但仍然出现该错误。我想知道初始设置是否不正确。我尝试获取 currentSession (
sessionFactory.getCurrentSession()) 并抛出错误
标签: java multithreading hibernate