Java 将服务层传递给线程的正确方法
我的服务层方法是事务性的,当我使用ExecutorService并将任务提交给线程时,我无法将servicelayer作为参数传递给每个线程,因为我得到了错误消息Java 将服务层传递给线程的正确方法,java,spring,multithreading,Java,Spring,Multithreading,我的服务层方法是事务性的,当我使用ExecutorService并将任务提交给线程时,我无法将servicelayer作为参数传递给每个线程,因为我得到了错误消息 Dec 14, 2009 10:40:18 AM com.companyx.applicationtest.applicationtestcompanyx.services.threadtestRunnable run SEVERE: null org.hibernate.HibernateException: No Hibernat
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)
我的服务层
一般来说,正如评论中所说,事务不应该在多个线程中运行。然而,在某些情况下,这是可以接受的
- 您需要与web服务进行一些异步通信(而不必让用户等待结果),并在结果出现时存储结果
- 在多线程中需要只读事务
new
创建线程,则它不是spring上下文的一部分。因此,当创建线程的方法完成时,您的事务拦截器将关闭事务(并最终关闭会话),您将得到上述异常
(有关更多详细信息,请参阅“查找注入”)
您需要在spring上下文中创建线程。由于您可能是从一个singleton
bean创建它们,因此从singleton
bean创建prototype
bean的情况很少见。因此,为了在spring上下文中创建线程,可以使用:
<bean id="mainBean"
class="com.my.MyClass">
<lookup-method name="createThread" bean="myThreadBean"/>
</bean>
您还应该在applicationContext.xml
中映射ThreadtestRunnable
类,或者将其注释为@Component(“myThreadBean”)
然后在名为
createThread
的主bean上定义一个abstract
方法,并返回线程类。使用@Transactional
(或定义适当的aop规则)注释您的run方法,然后尝试。也许您需要设置propagation=propagation。在@Transactional
中需要\u NEW“
。如果有任何错误,请返回此处。通常,正如注释中所述,事务不应在多个线程中运行。但是,在某些情况下,这是可以接受的
- 您需要与web服务进行一些异步通信(而不必让用户等待结果),并在结果出现时存储结果
- 在多线程中需要只读事务
new
创建线程,它不是spring上下文的一部分。因此,当创建线程的方法完成时,事务拦截器将关闭事务(以及最终的会话),您将获得上述异常
(有关更多详细信息,请参阅“查找注入”)
您需要在spring上下文中创建线程。由于您可能是从singleton
bean创建线程,因此从singleton
bean创建prototype
bean的情况非常罕见。因此,为了在spring上下文中创建线程,您可以使用:
<bean id="mainBean"
class="com.my.MyClass">
<lookup-method name="createThread" bean="myThreadBean"/>
</bean>
您还应该在applicationContext.xml
中映射ThreadtestRunnable
类,或者将其注释为@Component(“myThreadBean”)
然后在名为
createThread
的主bean上定义一个abstract
方法,并返回线程类。用@Transactional
注释您的run方法(或定义适当的aop规则),然后重试。也许您需要设置propagation=propagation.REQUIRES\u NEW“
在您的@Transactional
中。如果有什么问题,请回到这里。我不熟悉该框架,但是,在多个线程中运行事务有意义吗?通常,事务是预定义的操作序列。如果事务中确实需要并行计算,则可以在工作线程中运行它们,但让它们将结果报告回事务线程,然后将结果提交到数据库。正在寻找对此的评论。。事务应该在多线程中吗?我不熟悉这个框架,但是,在多线程中运行事务有意义吗?通常,事务是预定义的操作序列。如果事务中确实需要并行计算,则可以在工作线程中运行它们,但让它们将结果报告回事务线程,然后将结果提交到数据库。正在寻找对此的评论。。事务是否应该在多个线程中?通过在xml中注册线程。我不再应该在ExecutionService中调用新的threadtestRunnable((长)项,collectionAfterfiltered,this),对吗?并使用applicationContext.getbean(“线程”)?不,您应该调用createThread方法,它将为您创建线程。为什么不使用@Configurable并尽量减少所需的代码更改,只需要在ThreadTestRunnablee中添加注释呢?这样应该可以。但是添加@Configurable不会节省太多配置;)您将为查找方法保存一个like,并将其替换为加载时间的一行weaving@cometta@Bozho hi,如何通过在xml中注册线程来访问run()
方法中的项目。我不再应该在ExecutionService中调用新的threadtestRunnable((长)项,collectionAfterfiltered,this),对吗?并使用applicationContext.getbean(“线程”)?不,您应该调用createThread方法,它将为您创建线程。为什么不使用@Configurable并尽量减少所需的代码更改,只需要在ThreadTestRunnablee中添加注释呢?这样应该可以。但是添加@Configurable不会节省太多配置;)您将为查找方法保存一个like,并将其替换为加载时间的一行weaving@cometta@Bozho hi,如何访问run()
方法中的项目?