Java 冲突的春季时间表
我有两个按不同时间间隔运行的计划任务。第一个任务计划每5秒运行一次,第二个任务计划每10分钟运行一次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() }
@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我使用调度程序运行它。我想如果你发布“完整”或更多的代码,我们可能会看到一些其他问题。