java - 休眠和中断异常
问题描述
我有一个使用休眠并在 glassfish 中上传的 vaadin 应用程序,我们收到此错误:
AdmissionWeb:2018-07-03 12:01:06 [WARN ][http-listener-2(15)]com.mchange.v2.resourcepool.BasicResourcePool: com.mchange.v2.resourcepool.BasicResourcePool@1c40470 -- an attempt to checkout a resource was interrupted, and the pool is still live: some other thread must have either interrupted the Thread attempting checkout!
java.lang.InterruptedException
at java.lang.Object.wait(Native Method)
at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1414)
at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:606)
at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:526)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutAndMarkConnectionInUse(C3P0PooledConnectionPool.java:755)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:682)
at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:140)
at org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider.getConnection(C3P0ConnectionProvider.java:84)
at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:292)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:214)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:157)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:67)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:160)
at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1432)
at sun.reflect.GeneratedMethodAccessor2260.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:352)
at com.sun.proxy.$Proxy648.beginTransaction(Unknown Source)
at no.solarsoft.venus2.admissionweb2.DatabaseUtil.getSession(DatabaseUtil.java:52)
at no.solarsoft.venus2.admissionweb2.model.DataManager.getAdmission(DataManager.java:845)
at no.solarsoft.venus2.admissionweb2.AdmissionWebUI.init(AdmissionWebUI.java:178)
at com.vaadin.ui.UI.doInit(UI.java:675)
at com.vaadin.server.communication.UIInitHandler.getBrowserDetailsUI(UIInitHandler.java:214)
at com.vaadin.server.communication.UIInitHandler.synchronizedHandleRequest(UIInitHandler.java:74)
at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1408)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:364)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.glassfish.tyrus.servlet.TyrusServletFilter.doFilter(TyrusServletFilter.java:253)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
at java.lang.Thread.run(Thread.java:745)]]
我不知道为什么会这样。一切似乎都很正常。
这是 hibernate.cfg.xml :
<hibernate-configuration>
<session-factory>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.c3p0.idle_test_period"> 120</property> <!-- In seconds -->
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.timeout">3600</property>
<property name="hibernate.c3p0.max_statements">100</property>
<property name="c3p0.acquire_increment">1</property>
我们有一个递归方法 handlePayment(),它每 10 秒调用一次,直到我们发布回调、支付失败或超时(超时设置为 60 分钟。
private PxPaymentResponseData handlePayment(String paymentId, long timeoutTimestamp, boolean shouldPostCallback, String admissionId) throws Exception {
List<String> nodesToExpand = Arrays.asList("urls", "transactions", "payeeInfo", "prices");
PayExAccountV2 pxAccount = PayExUtil.findPayExAccountForAdmission(admissionId);
PxPaymentResponse pxPayment = PxPaymentService.getPayment(paymentId, nodesToExpand, pxAccount.getToken());
Optional<PxTransactionData> lastTx = PxPaymentUtil
.findLastTransaction(pxPayment.getPaymentData().getTransactions().getTransactionList());
if (lastTx.isPresent()) {
PxTransactionData txData = lastTx.get();
String state = txData.getState();
if (PxTransaction.State.COMPLETED.value().equalsIgnoreCase(state)) {
if (PxTransaction.Type.CAPTURE.value().equalsIgnoreCase(txData.getType())) {
return pxPayment.getPaymentData();
} else if (PxTransaction.Type.AUTHORIZATION.value().equalsIgnoreCase(txData.getType())) {
if (shouldPostCallback) {
CompletableFuture.runAsync(() -> issuePayExCallback(pxPayment.getPaymentData(), txData, admissionId));
}
wait(pxPayment.getPaymentData().getId(), PAYEX_REQUEST_DELAY, timeoutTimestamp);
return handlePayment(paymentId, timeoutTimestamp, false, admissionId);
}
} else if (PxTransaction.State.INITIALIZED.value().equalsIgnoreCase(state)) {
wait(pxPayment.getPaymentData().getId(), PAYEX_REQUEST_DELAY, timeoutTimestamp);
return handlePayment(paymentId, timeoutTimestamp, false, admissionId);
} else if (PxTransaction.State.FAILED.value().equalsIgnoreCase(state)) {
if (PxTransaction.Type.AUTHORIZATION.value().equalsIgnoreCase(txData.getType())
|| PxTransaction.Type.CAPTURE.value().equalsIgnoreCase(txData.getType())) {
handleFailedPayment(pxPayment.getPaymentData(), txData);
}
}
} else {
log.warn("Could not find any transactions for payment: " + paymentId);
}
throw new Exception("Payment not handled!");
}
wait() 方法调用 Thread.sleep()。
private void wait(String paymentId, final int seconds, long timeoutTimestamp)
throws Exception {
if (isTimeoutElapsed(timeoutTimestamp)) {
throw new PaymentTimeoutException("Payment processing session has timed out for payment " + paymentId);
}
try {
Thread.sleep(seconds * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
我不知道错误是否与 wait() 方法有关。我希望有一个人可以帮助我。我们已将 glassfish 的最大池大小增加到 200,但这并没有帮助。
谢谢!
解决方案
您的 Glassfish 配置设置为比您定义的睡眠时间更快地中断线程。
有关更多详细信息,请参阅此:如何避免线程中断异常
推荐阅读
- c# - 如何按列对数据集进行排序
- ethereum - 松露智能合约错误:参数数量无效
- php - 在Angular 6中显示来自api的对象
- hibernate - micronaut 有没有办法让“Spring Data JPA”存储库像在 spring 中那样从接口自动生成?
- mysql - 行大小为 8135,大于最大允许大小 (8126)
- jenkins - Jenkins中的参数化项目:参数未传递
- maxima - 如何在泰勒级数中展开函数组合?
- php - PHP Google API 客户端更新库问题
- common-lisp - 如何设置iolib超时
- azure-active-directory - CAS 与多个 OpenID 提供者的集成