有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java将服务层传递给线程的正确方法

我的服务层方法是事务性的,当我使用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. 正确的方法是什么,我需要每个线程在服务层调用方法?(我正在使用spring)

共 (1) 个答案

  1. # 1 楼答案

    一般来说,正如评论中所说,事务不应该在多个线程中运行。然而,在某些情况下,这是可以接受的

    • 您需要与web服务进行一些异步通信(而不是让用户等待结果),并在结果出现时存储结果
    • 在多个线程中需要只读事务

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

    (有关更多详细信息,请参阅“查找注入”)

    您需要在spring上下文中创建线程。由于您可能是从singletonbean创建它们,因此从singletonbean创建prototypebean的情况很少见。因此,为了在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"。如果有什么不对劲,就回来