Java 冲突的春季时间表

Java 冲突的春季时间表,java,spring,hibernate,spring-boot,spring-data,Java,Spring,Hibernate,Spring Boot,Spring Data,我有两个按不同时间间隔运行的计划任务。第一个任务计划每5秒运行一次,第二个任务计划每10分钟运行一次 @EnableScheduling public class ScheduledTask { @Autowired private taskService taskService; @Scheduled(every 5 second) public void scheduleTaskA() { taskService.taskA() }

我有两个按不同时间间隔运行的计划任务。第一个任务计划每5秒运行一次,第二个任务计划每10分钟运行一次

@EnableScheduling
public class ScheduledTask {

    @Autowired
    private taskService taskService;

    @Scheduled(every 5 second)
    public void scheduleTaskA() {
        taskService.taskA()
    }

    @Scheduled(every 10 minute)
    public void scheduleTaskB() {
        taskService.taskB()
    }
}

public class TaskServiceImpl implements TaskService {

    @PersistenceContext
    private EntityManager entityManager;

    void taskA(){
        StoredProcedureQuery query = entityManager.createStoredProcedureQuery("callStoreProcedure1"); 

        if(query.execute()) 
            query.getSingleResult();        

    }

    void taskB(){
        StoredProcedureQuery query = entityManager.createStoredProcedureQuery("callStoreProcedure2"); 

        if(query.execute())
            query.getSingleResult();                    
    }
}
每次运行第二个任务时,它都会抛出
java.lang.IllegalStateException:Session/EntityManager关闭。看起来第一个任务是关闭entityManager。在不更改@PersistenceContext注释的情况下,如何避免这种情况

全堆栈跟踪

java.lang.IllegalStateException: Session/EntityManager is closed
    at org.hibernate.internal.AbstractSharedSessionContract.checkOpen(AbstractSharedSessionContract.java:357) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
    at org.hibernate.engine.spi.SharedSessionContractImplementor.checkOpen(SharedSessionContractImplementor.java:138) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
    at org.hibernate.query.internal.AbstractProducedQuery.getMaxResults(AbstractProducedQuery.java:892) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
    at org.hibernate.procedure.internal.ProcedureCallImpl.getResultList(ProcedureCallImpl.java:716) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
    at org.hibernate.procedure.internal.ProcedureCallImpl.getSingleResult(ProcedureCallImpl.java:744) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
    at sun.reflect.GeneratedMethodAccessor150.invoke(Unknown Source) ~[na:na]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_171]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_171]
    at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:374) ~[spring-orm-4.3.18.RELEASE.jar:4.3.18.RELEASE]
    at com.sun.proxy.$Proxy149.getSingleResult(Unknown Source) ~[na:na]
    at com.test.service.TaskServiceImpl.taskA(TaskServiceImpl.java:602) ~[classes/:0.0.1-SNAPSHOT]
    at com.test.service.TaskServiceImpl....(TaskServiceImpl.java:112) ~[classes/:0.0.1-SNAPSHOT]
    at com.test.service.TaskServiceImpl....(TaskServiceImpl.java:163) ~[classes/:0.0.1-SNAPSHOT]
    at com.test.schedule.ScheduledTask.scheduledTaskA(ScheduledTask.java:45) ~[classes/:0.0.1-SNAPSHOT]
    at sun.reflect.GeneratedMethodAccessor143.invoke(Unknown Source) ~[na:na]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_171]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_171]
    at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65) ~[spring-context-4.3.18.RELEASE.jar:4.3.18.RELEASE]
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-4.3.18.RELEASE.jar:4.3.18.RELEASE]
    at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81) [spring-context-4.3.18.RELEASE.jar:4.3.18.RELEASE]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_171]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_171]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_171]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [na:1.8.0_171]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_171]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_171]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_171]

我非常确定您需要在事务上下文中运行StoredProcedureQuery。请尝试将@Transactional添加到每个方法中

@Transactional
void taskA(){
    StoredProcedureQuery query = entityManager.createStoredProcedureQuery("callStoreProcedure1"); 

    if(query.execute()) 
        query.getSingleResult();        

}

@Transactional
void taskB(){
    StoredProcedureQuery query = entityManager.createStoredProcedureQuery("callStoreProcedure2"); 

    if(query.execute())
        query.getSingleResult();                    
}

您可能还希望将传播设置为“新建”,以确保它们在各自单独的事务@tansacional(传播=传播.需要\u new)中运行。

由于您试图共享同一个实体管理器,因此出现错误。这是短生命物体

您可以应用以下两种解决方案:

1) 注入EntityManager工厂和EntityManager内部,在方法use factory中创建EntityManager

  @PersistenceUnit(unitName= "em")
  private EntityManagerFactory emf; 
2) 创建两个不同的服务,让每个服务都有自己的实体管理器实例。
(当调度程序调用方法时,不确定它是否能再次工作。请测试它并让我知道。)

Add@Stateful on class header我检查了代码。对我来说,它可以工作。您正在使用的是
entityManager
,它可能自动没有打开的连接。您是否在其他地方使用entitymanager
@PersistenceContext
表示entitymanager直接由spring/jpa管理。您可能已在其他地方关闭了此连接。@Acewin连接已打开,但在执行
query时。getSingleResult()
会抛出error@tangobee我使用调度程序运行它。我想如果你发布“完整”或更多的代码,我们可能会看到一些其他问题。