我有一个JSF/JPA/MySQL/EclipseLink GlassFish或Payara应用程序。
时间表正在无状态EJB中运行。数据是使用无状态bean中的EJB通过JPQL提取的。
当数据库查询少量数据时,应用程序运行时不会出现任何问题。当处理大量数据时,会出现错误。错误发生的地方因时间而异。在指向错误的代码段中没有错误,因为相同的代码在检索少量数据时没有任何问题。将相同的代码复制并粘贴到JSF托管的bean中,可以使用大量数据正确运行。(它不能在生产中使用,因为查询应该在计划中运行。(
这个问题的原因是什么?是否有可以优化的MySQL/GlassFish设置来防止此错误?
错误示例
Warning: A system exception occurred during an invocation on EJB IndividualQueryResultFacade, method: public void lk.gov.health.phsp.facade.AbstractFacade.edit(java.lang.Object)
Warning: javax.ejb.TransactionRolledbackLocalException: Client's transaction aborted
at com.sun.ejb.containers.EJBContainerTransactionManager.useClientTx(EJBContainerTransactionManager.java:361)
at com.sun.ejb.containers.EJBContainerTransactionManager.preInvokeTx(EJBContainerTransactionManager.java:255)
at com.sun.ejb.containers.BaseContainer.preInvokeTx(BaseContainer.java:4558)
at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:2020)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:210)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
at com.sun.proxy.$Proxy412.edit(Unknown Source)
at lk.gov.health.phsp.facade.__EJB31_Generated__IndividualQueryResultFacade__Intf____Bean__.edit(Unknown Source)
at lk.gov.health.phsp.ejbs.ReportTimerSessionBean.calculateIndividualQueryResult(ReportTimerSessionBean.java:692)
at lk.gov.health.phsp.ejbs.ReportTimerSessionBean.runIndividualQuerys(ReportTimerSessionBean.java:151)
at sun.reflect.GeneratedMethodAccessor174.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081)
at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153)
at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4820)
at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:656)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:824)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
at org.jboss.weld.module.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:81)
at org.jboss.weld.module.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:52)
at sun.reflect.GeneratedMethodAccessor90.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:823)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doCall(SystemInterceptorProxy.java:163)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundTimeout(SystemInterceptorProxy.java:145)
at sun.reflect.GeneratedMethodAccessor99.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:823)
at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:369)
at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:4792)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4780)
at com.sun.ejb.containers.BaseContainer.callEJBTimeout(BaseContainer.java:4085)
at com.sun.ejb.containers.EJBTimerService.deliverTimeout(EJBTimerService.java:1200)
at com.sun.ejb.containers.EJBTimerService.access$000(EJBTimerService.java:89)
at com.sun.ejb.containers.EJBTimerService$TaskExpiredWork.run(EJBTimerService.java:1919)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
无状态Bean-下面只显示一小段。
@无国籍公共类ReportTimerSessionBean{
private boolean processingReport = false;
@EJB
private StoredQueryResultFacade storeQueryResultFacade;
@EJB
private UploadFacade uploadFacade;
@EJB
private EncounterFacade encounterFacade;
@EJB
private QueryComponentFacade queryComponentFacade;
@EJB
private ClientEncounterComponentItemFacade clientEncounterComponentItemFacade;
@EJB
private ConsolidatedQueryResultFacade consolidatedQueryResultFacade;
@EJB
private IndividualQueryResultFacade individualQueryResultFacade;
private List<QueryComponent> queryComponents;
@Schedule(
hour = "*",
minute = "*",
second = "1",
persistent = false)
@TransactionAttribute(REQUIRES_NEW)
public void runReports() {
queryComponents = null;
if (!processingReport) {
submitToConsilidate();
}
if (!processingReport) {
checkCompletenessAfterConsolidation();
}
if (!processingReport) {
generateFileAfterConsolidation();
}
}
@Schedule(
hour = "*",
minute = "*",
second = "16",
persistent = false)
@TransactionAttribute(REQUIRES_NEW)
public void runIndividualQuerys() {
System.out.println("Going to run individual queries at " + currentTimeAsString() + ".");
int singleProcessCount = 5000;
List<IndividualQueryResult> cqrs;
String j;
j = "select r "
+ " from IndividualQueryResult r "
+ " where r.included is null "
+ " order by r.id "
+ " ";
cqrs = getIndividualQueryResultFacade().findByJpql(j, singleProcessCount);
if (cqrs == null) {
System.out.println("No individual queries left to process.");
return;
}
System.out.println("Number of individual queries processing this time is " + cqrs.size());
for (IndividualQueryResult r : cqrs) {
calculateIndividualQueryResult(r);
}
}
@Schedule(
hour = "*",
minute = "*",
second = "31",
persistent = false)
@TransactionAttribute(REQUIRES_NEW)
public void createIndividualResultsForConsolidatedResults() {
System.out.println("Going to create individual queries at " + currentTimeAsString());
int singleProcessCount = 50;
List<ConsolidatedQueryResult> cqrs;
String j;
j = "select r "
+ " from ConsolidatedQueryResult r "
+ " where r.longValue is null "
+ " order by r.id "
+ " ";
cqrs = getConsolidatedQueryResultFacade().findByJpql(j, singleProcessCount);
if (cqrs == null) {
System.out.println("No consolidated queries to create individual queries.");
return;
}
for (ConsolidatedQueryResult r : cqrs) {
Long lastIndividualQueryResultId = 0l;
List<Long> encIds = findEncounterIds(r.getResultFrom(), r.getResultTo(), r.getInstitution());
if (encIds == null) {
r.setLongValue(0l);
getConsolidatedQueryResultFacade().edit(r);
continue;
}
if (encIds.isEmpty()) {
r.setLongValue(0l);
getConsolidatedQueryResultFacade().edit(r);
continue;
}
for (Long encId : encIds) {
Long generatedId = createIndividualQueryResultsForConsolidateQueryResult(encId,
r.getQueryComponentCode());
if (generatedId > lastIndividualQueryResultId) {
lastIndividualQueryResultId = generatedId;
}
}
r.setLastIndividualQueryResultId(lastIndividualQueryResultId);
getConsolidatedQueryResultFacade().edit(r);
}
}
您将@EJB用于无状态bean。相反,尝试定义实体管理器端的无状态bean,并在中进行所有数据事务。实体管理器不是线程安全的。