【问题标题】:correct way to pass service layer to threads将服务层传递给线程的正确方法
【发布时间】:2009-12-14 03:04:16
【问题描述】:

我的服务层方法是事务性的,当我使用 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
                  }
  1. 我应该像这样将服务层传递给每个线程吗?
  2. 什么是正确的方法,我需要每个线程调用服务层中的方法? (我用的是弹簧)

【问题讨论】:

  • 我不熟悉框架,但是,在多个线程中运行事务是否有意义?通常,事务是预定义的操作序列。如果您确实需要在事务中进行并行计算,您可以在工作线程中运行它们,但让它们将结果报告回您将它们提交到数据库的事务线程。
  • 找人评论这个..事务应该在多个线程中吗?

标签: java spring multithreading


【解决方案1】:

通常,如 cmets 所述,事务不应在多个线程中运行。但是,在某些情况下,它是可以接受的。

  • 您需要与 Web 服务进行一些异步通信(不让用户等待结果),并在结果到来时存储结果
  • 您需要多个线程中的只读事务。

如果您使用new 创建线程,则它不是弹簧上下文的一部分。因此,当创建线程的方法完成时,您的事务拦截器将关闭事务(以及最终的会话),您将得到上述异常。

(更多详情-Spring docs,见“查找注​​入”)

您需要在 spring 上下文中创建线程。由于您可能是从 singleton bean 创建它们,因此从 singleton bean 创建 prototype bean 的情况很少见。所以为了在spring上下文中创建线程,可以使用:

 <bean id="mainBean"
    class="com.my.MyClass">
    <lookup-method name="createThread" bean="myThreadBean"/>
 </bean>

您还应该将ThreadtestRunnable 类映射到applicationContext.xml 或将其注释为@Component("myThreadBean")

然后在名为createThread 的主bean 上定义一个abstract 方法并返回您的线程类。用@Transactional 注释你的run 方法(或定义适当的aop 规则),然后尝试一下。也许您需要在您的@Transactional 中设置propagation=Propagation.REQUIRES_NEW"。如果有任何问题,请回到这里。

【讨论】:

  • 通过在 xml 中注册线程。我不再应该在 ExecutionService 中调用 new threadtestRunnable((Long)item,collectionAfterfiltered,this) 对吗?并使用 applicationContext.getbean("thread") ?
  • 不,你应该调用你的 createThread 方法,它会为你创建线程
  • 为什么不直接使用@Configurable,尽量减少代码变更,只需要在ThreadtestRunnable中添加注解
  • 任何一种方式都应该有效。但是添加 @Configurable 不会节省太多配置;)您将保存一个类似的查找方法替换为加载时编织的一行
  • @cometta @Bozho hi,如何访问run()方法中的items
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-06
  • 1970-01-01
  • 1970-01-01
  • 2022-07-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多