我的服务层方法是事务性的,当我使用ExecutorService并将任务提交给线程时,我无法将servicelayer作为参数传递给每个线程,因为我收到错误
Dec 14, 2009 10:40:18 AM com.companyx.applicationtest.applicationtestcompanyx.services.threadtestRunnable run
SEVERE: null
org.hibernate.HibernateException: No Hibernate Session bound to thread, and conf
iguration does not allow creation of non-transactional one here
at org.springframework.orm.hibernate3.SpringSessionContext.currentSessio
n(SpringSessionContext.java:63)
at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactor
yImpl.java:542)
ExecutorService executor = Executors.newFixedThreadPool(10);
for (final Object item : CollectionsTest{
executor.submit(new threadtestRunnable((Long)item,collectionAfterfiltered,this)); //'this' is service layer
}
答案 0 :(得分:3)
通常,如评论中所述,不应在多个线程中运行事务。但是,有些情况可以接受。
如果使用new
创建线程,则它不属于spring上下文。因此,当创建线程的方法完成时,您的事务拦截器将关闭事务(和最终的会话),并且您将获得上述异常。
(有关详细信息 - Spring docs,请参阅“查找注入”)
您需要在spring上下文中创建线程。由于您可能正在从singleton
bean创建它们,因此从prototype
bean创建singleton
bean的情况很少见。因此,为了在spring上下文中创建一个线程,您可以使用:
<bean id="mainBean"
class="com.my.MyClass">
<lookup-method name="createThread" bean="myThreadBean"/>
</bean>
您还应该将ThreadtestRunnable
课程映射到applicationContext.xml
或将其注释为@Component("myThreadBean")
。
然后在名为abstract
的主bean上定义createThread
方法并返回您的线程类。使用@Transactional
注释您的run方法(或定义相应的aop规则),然后尝试一下。也许您需要在propagation=Propagation.REQUIRES_NEW"
中设置@Transactional
。如果有任何问题,请回到这里。