我需要创建一个过程,该过程将查询Web服务以提取信息,然后将数据保存在数据库中。但是,由于此过程非常耗时,因此我想使其在后台运行。
当前,我有一个ProcessHandler
,它由UI中的按钮调用。该处理程序创建一个Thread
,该CC应该在后台运行该进程。但是,我收到HibernateException
和消息No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
。
我在一个配置xml文件(有多个)中定义了ProcessHandler
,如下所示(这是一个非常通用的定义):
<bean class="com.project.ProcessHandler" parent="parentHandler" />
在
ProcessHandler
中,调用此过程的代码也非常通用:Thread t = new Thread(new WorkerThread(alphaManager, bravoManager, charlieManager));
t.start();
这是
WorkerThread
的当前实现:public class WorkerThread implements Runnable {
private Manager alphaManager;
private Manager bravoManager;
private Manager charlieManager;
public WorkerThread() {
this.alphaManager = null;
this.bravoManager = null;
this.charlieManager= null;
}
public WorkerThread(Manager alphaManager, Manager bravoManager, Manager charlieManager) {
this.alphaManager = alphaManager;
this.bravoManager = bravoManager;
this.charlieManager= charlieManager;
}
@Override
public void run() {
// code to query webservice and extract data...
saveToDbMethod(data);
}
@Transactional(propagation = Propagation.REQUIRED)
private void saveToDbMethod(String data) {
// code to process data...
alphaManager.save(entityA);
bravoManager.save(entityB);
charlieManager.save(entityC);
}
}
默认构造函数是我尝试将
WorkerThread
定义为config xml文件(之一)中的bean时的遗留物。有人可以通过给我一些有关如何解决此问题的提示来帮助我吗?
最佳答案
问题是您手动创建线程,并期望它的行为像spring托管bean。
由于ProcessHandler
是合法的bean,因此我将执行以下操作:
1)创建一个seaparate服务类,该类将管理者作为依赖项,并使用@Transactional
方法:
@Service
public class Service{
private Manager alphaManager;
private Manager bravoManager;
private Manager charlieManager;
public Service(Manager alphaManager, Manager bravoManager, Manager charlieManager) {
this.alphaManager = alphaManager;
this.bravoManager = bravoManager;
this.charlieManager= charlieManager;
}
@Transactional(propagation = Propagation.REQUIRED)
private void saveToDbMethod(String data) {
// code to process data...
alphaManager.save(entityA);
bravoManager.save(entityB);
charlieManager.save(entityC);
}
}
2)将
Service
注入ProcessHandler
中:<bean class="com.project.ProcessHandler" parent="parentHandler">
<property name="service" ref="service">
</bean>
3)最后将
Service
传递给WorkerThread
:public class WorkerThread implements Runnable {
private Service service;
public WorkerThread(Service service) {
this.service = service;
}
@Override
public void run() {
// code to query webservice and extract data...
service.saveToDbMethod(data);
}
}
和:
Thread t = new Thread(new WorkerThread(service));
t.start();
现在,您的操作应该是事务性的,并且应该在会话中进行。