我们有一个应用程序,我们使用H2嵌入式数据库来存储数据。我们有一个同步写入方法,可以进行数据库插入。由于H2 DB是一个小型Java嵌入式数据库,因此我们在write方法上使用“synchronized”来处理嵌入式DB而不是DB中的事务管理。
但是在负载很重的时候,我们可以看到写线程被挂起了。我们不确定哪个资源,这个帖子被挂起了。
请查看以下代码片段:
public synchronized int write(IEvent event) {
String methodName = "write";
Connection conn = null;
PreparedStatement updtStmt = null;
Statement stmt = null;
ResultSet rSet = null;
int status = 0;
try {
dbConnect.checkDBSizeExceed();
conn = dbConnect.getConnection();
updtStmt = conn.prepareStatement(insertQuery);
updtStmt.setString(1, (String) event.getAttributeValue());
......
updtStmt.setString(30, (String) event.getAttributeValue());
updtStmt.setBoolean(31, false);
status = updtStmt.executeUpdate();
}catch(SQLException ex){
logger.log(methodName,logger.print(ex),Logger.ERROR);
} catch(Exception ex){
logger.log(methodName,logger.print(ex),Logger.ERROR);
} finally {
try {
if (updtStmt != null)
updtStmt.close();
if (conn != null)
conn.close();
}catch(SQLException ex) {
logger.log(methodName,logger.print(ex),Logger.ERROR);
return status;
}
return status;
}
}
我们有多个可以访问此DB的写入方法。从代码中我们可以看到代码很简单。但我们不确定资源被锁定的位置。
另一个问题是在(Websphere)system.out中的线程转储中,我们可以看到线程堆栈跟踪如下所示。
[6/15/12 3:13:38:225 EDT] 00000032 ThreadMonitor W WSVR0605W: Thread "WebContainer : 3" (00000066) has been active for 632062 milliseconds and may be hung. There is/are 2
thread(s) in total in the server that may be hung.
at com.xxxx.eaws.di.agent.handlers.AuditEmbeddedDBHandler.store(Unknown Source)
at com.xxxx.eaws.di.agent.eventlogger.2LoggerImpl.logEvent(Unknown Source)
at com.xxxx.eecs.eventlogger.EventLoggerAdapter.logAuditEvent(EventLoggerAdapter.java:682)
at com.xxxx.eecs.eventlogger.EventLoggerAdapter.logEvent(EventLoggerAdapter.java:320)
at com.xxxx.eecs.eventlogger.EventLogger.logEventInternal(EventLogger.java:330)
at com.xxxx.eecs.eventlogger.EventLogger.logEvent(EventLogger.java:283)
at com.ibm.wps.auth.impl.ImplicitLoginFilterChainImpl.login(ImplicitLoginFilterChainImpl.java:55)
at com.ibm.wps.auth.impl.AuthenticationFilterChainHandlerImpl.invokeImplicitLoginFilterChain(AuthenticationFilterChainHandlerImpl.java:393)
at com.ibm.wps.auth.impl.InitialAuthenticationHandlerImpl.checkAuthentication(InitialAuthenticationHandlerImpl.java:204)
at com.ibm.wps.state.phases.PhaseManagerImpl.callInitialAuthenticationHandler(PhaseManagerImpl.java:240)
在上面的堆栈跟踪中,我需要知道我在堆栈跟踪中获取“Unknown Source”的原因。这些jar在类路径中可用,我们在类路径中也有H2.jar。我们不确定为什么,如果线程在H2中挂起,我们就无法获得线程堆栈跟踪。
如果没有,我还需要知道为什么线程堆栈跟踪显示“Unknown Source”。
感谢您的帮助。
提前致谢。
答案 0 :(得分:0)
您使用的是ejbs吗?你如何获得连接?它是由aop服务器注入的吗?你是从jndi找回来的吗?您不应该同步该方法。 即使它是嵌入式数据库,您也应该依赖应用服务器设施。 您需要将连接配置为数据源,即使您的数据库在内存中也是如此。如果要在db上进行序列化写入,则需要将连接池配置为序列化ansi隔离级别(there are 4 ansi isolation levels)。通过这种方式,您应该在没有同步的托管环境(应用服务器)中获得相同的效果,应该在应用服务器内避免使用。
答案 1 :(得分:0)
未知来源通常意味着行号可用。
编译时,编译器可以添加行号等调试信息。如果它们不存在于JAR或.class文件中,则JVM无法为您提供该信息。
HTH
答案 2 :(得分:0)
看起来像conn = dbConnect.getConnection();等待超过60000ms。
WAS抛出的错误是因为资源适配器有一个机制轮询周期。它被认为是为新的入站事件轮询企业信息系统(EIS)事件存储的速率(以毫秒为单位)。轮询周期以固定速率建立,这意味着如果轮询周期的执行因任何原因而延迟,则下一个周期将立即发生以“赶上”。在轮询期间,轮询线程将处于休眠状态。 一旦计算时间为60000毫秒,WebSphere Application Server线程监视器将此轮询线程视为挂起并抛出异常。