java – 使用Spring Data和Hibernate时如何正确执行后台线程?
我正在构建一个使用
Spring Data和Hibernate的简单Tomcat webapp.有一个终点可以完成很多工作,因此我想将工作卸载到后台线程,以便在完成工作时Web请求不会挂起10分钟.所以我在一个组件扫描包中写了一个新服务:
@Service public class BackgroundJobService { @Autowired private ThreadPoolTaskExecutor threadPoolTaskExecutor; public void startJob(Runnable runnable) { threadPoolTaskExecutor.execute(runnable); } } 然后在Spring中配置ThreadPoolTask??Executor: <bean id="threadPoolTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <property name="corePoolSize" value="5" /> <property name="maxPoolSize" value="10" /> <property name="queueCapacity" value="25" /> </bean> 这一切都很有效.但问题来自Hibernate.在我的runnable中,查询只有一半工作.我可以: MyObject myObject = myObjectRepository.findOne() myObject.setSomething("something"); myObjectRepository.save(myObject); 但是如果我有延迟加载的字段,它会失败: MyObject myObject = myObjectRepository.findOne() List<Lazy> lazies = myObject.getLazies(); for(Lazy lazy : lazies) { // Exception ... } 我收到以下错误: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.stackoverflow.MyObject.lazies,could not initialize proxy - no Session 所以我觉得(Hibernate新手)新线程在这些自制线程上没有会话,但Spring Data会自动为HTTP Request线程创建新会话. >有没有办法从会话中手动启动新会话? 我已经能够通过在@Transactional方法中做一些事情来解决它,但我很快就知道这不是一个非常好的解决方案,因为这不会让我使用适用于Web请求的方法. 谢谢. 解决方法
使用Spring,您不需要自己的执行程序.一个简单的注释@Async将为您完成工作.只需使用它在您的服务中注释您的heavyMethod并返回void或Future对象,您将获得一个后台线程.我会避免在控制器级别使用异步注释,因为这将在请求池执行程序中创建一个异步线程,并且您可能会用完“请求接受器”.
你的懒惰异常的问题出现在你没有会话的新线程中.为避免此问题,您的异步方法应该处理完整的工作.不要提供以前加载的实体作为参数.该服务可以使用EntityManager,也可以是事务性的. 我自己不合并@Async和@Transactional所以我可以以任何一种方式运行服务.我只是在服务周围创建异步包装器,如果需要,可以使用它. (这简化了测试) @Service public class AsyncService { @Autowired private Service service; @Async public void doAsync(int entityId) { service.doHeavy(entityId); } } @Service public class Service { @PersistenceContext private EntityManager em; @Transactional public void doHeavy(int entityId) { // some long running work } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 在Java中使用字节数组序列化类
- 动手动脑
- java – 以编程方式抛出NullPointerException是否可以?
- java – 使NetBeans(ant)为一个项目生成多个jar文件
- Java基于栈方式解决汉诺塔问题实例【递归与非递归算法】
- Java各种对象(PO,BO,VO,DTO,POJO,DAO,Entity,JavaBean,Jav
- 解析Java的JNI编程中的对象引用与内存泄漏问题
- Java中的String对象数据类型全面解析
- 是否有可能从javax.naming.InitialContext获得“一切”?
- java – 为什么libgdx SpriteBatch / BitmapFont会破坏Text