带Servlet的Wildfly连接池&主题

时间:2016-05-12 08:47:44

标签: java multithreading servlets threadpool connection-pooling

我们有一个使用servlet,jsps和Threads的Web应用程序,它是一个MultiThreaded应用程序。我们使用JDK1.8,Wildfly服务器8.2。我创建了一个ContextListener,如下所示,使用JNDI数据源获取连接对象。这是使用连接池获取连接的正确方法吗?

AppContextListener.java

public class AppContextListener implements ServletContextListener
{

  /* (non-Javadoc)    
   * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)    
   */    
  @Override    
  public void contextDestroyed(ServletContextEvent servletContextEvent)
  {        
    ServletContext ctx = servletContextEvent.getServletContext();  
    DBConnectionManager dbManager = (DBConnectionManager)ctx.getAttribute("DBManager");      
    dbManager.closeConnection();  
  }

  /* (non-Javadoc)  
   * @see   javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)  
   */  
  @Override  
  public void contextInitialized(ServletContextEvent servletContextEvent)
  {  
    ServletContext ctx = servletContextEvent.getServletContext();  
    String jndiName = ctx.getInitParameter("JNDI");  

    //create database connection from context parameters and set it to context
    DBConnectionManager dbManager = new DBConnectionManager(jndiName);
    ctx.setAttribute("DBManager", dbManager);  
  }
}

DBConnectionManager.java

public class DBConnectionManager
{
  private static Logger logger=Logger.getLogger(DBConnectionManager.class);
  private static Connection conn;
  private String jndiName;

  public DBConnectionManager(String jndiName) {
    this.jndiName = jndiName;
    try {
       Context ctx = new InitialContext();
       DataSource ds = (DataSource) ctx.lookup(this.jndiName);
       conn = ds.getConnection();
       conn.setAutoCommit(false);
    } catch (NamingException | SQLException e) {
       logger.error("[DBConnectionManager.DBConnectionManager]Exception: "+e.getMessage());
    }    
  }

  public static Connection getConnection(){
     return conn; 
  }

  public void closeConnection(){
     if(conn != null){
       try {
          conn.close();
       } catch (SQLException e) {
          logger.error("[DBConnectionManager.closeConnection]Exception: "+e.getMessage());
       }
     }
  }
}

每当我需要一个连接对象时,我都会调用静态方法getConnection()。似乎我没有用这种方式实现连接池。我应该如何获得连接以实现连接池?

我的服务器将运行超过12小时当我尝试重新加载发送的消息时,表系统将抛出由于线程引起的以下异常。我该如何解决这个问题?

TxConnectionListener:380 - IJ000305: Connection error occured: org.jboss.jca.core.connectionmanager.listener.TxConnectionListener@bed9492[state=NORMAL managed connection=org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@5df6b58b connection handles=1 lastUse=1462985106208 trackByTx=false pool=org.jboss.jca.core.connectionmanager.pool.strategy.OnePool@1299562a mcp=SemaphoreArrayListManagedConnectionPool@3a1d6b71[pool=RDTSDS] xaResource=LocalXAResourceImpl@4b534943[connectionListener=bed9492 connectionManager=f7fbabb warned=false currentXid=null productName=Oracle productVersion=Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options jndiName=java:jboss/RDTSDS] txSync=null]
javax.resource.spi.ResourceAdapterInternalException: Unexpected error
    at org.jboss.jca.adapters.jdbc.BaseWrapperManagedConnection.broadcastConnectionError(BaseWrapperManagedConnection.java:644)
    at org.jboss.jca.adapters.jdbc.BaseWrapperManagedConnection.connectionError(BaseWrapperManagedConnection.java:610)
    at org.jboss.jca.adapters.jdbc.WrappedConnection.checkException(WrappedConnection.java:1640)
    at org.jboss.jca.adapters.jdbc.WrappedStatement.checkException(WrappedStatement.java:1267)
    at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.executeQuery(WrappedPreparedStatement.java:467)
    at com.ctsu.rdts.beans.ReconcileInfo.getNextMessage(ReconcileInfo.java:493)
    at com.ctsu.rdts.beans.GroupInfo.sendMessage(GroupInfo.java:818)
    at com.ctsu.rdts.app.GroupSendThread.send(GroupSendThread.java:114)
    at com.ctsu.rdts.app.GroupSendThread.run(GroupSendThread.java:68)
 Caused by: java.lang.ThreadDeath
    at java.lang.Thread.stop(Thread.java:850)
    at com.ctsu.rdts.app.HttpDequeue.stopThread(HttpDequeue.java:944)
    at com.ctsu.rdts.app.HttpDequeue.clearLocks(HttpDequeue.java:418)
    at com.ctsu.rdts.app.HttpDequeue.run(HttpDequeue.java:404)

服务器日志中的异常:

WARN  [org.jboss.as.connector.subsystems.datasources.AbstractDataSourceService$WildFlyLocalMCF] (NRG) Queued thread: ECOG-ACRIN: java.lang.Throwable: Queued thread: ECOG-ACRIN
    at sun.misc.Unsafe.park(Native Method) [rt.jar:1.8.0_66]
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) [rt.jar:1.8.0_66]
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836) [rt.jar:1.8.0_66]
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870) [rt.jar:1.8.0_66]
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199) [rt.jar:1.8.0_66]
    at java.util.concurrent.locks.ReentrantLock$FairSync.lock(ReentrantLock.java:224) [rt.jar:1.8.0_66]
    at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285) [rt.jar:1.8.0_66]
    at org.jboss.jca.adapters.jdbc.BaseWrapperManagedConnection.lock(BaseWrapperManagedConnection.java:373)
    at org.jboss.jca.adapters.jdbc.BaseWrapperManagedConnection.tryLock(BaseWrapperManagedConnection.java:388)
    at org.jboss.jca.adapters.jdbc.WrappedConnection.lock(WrappedConnection.java:147)
    at org.jboss.jca.adapters.jdbc.WrappedConnection.prepareCall(WrappedConnection.java:589)

我被困在这个问题上15天了。有人可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

检查此部分中的代码HttpDequeue和线程实现,您可以使用本指南替换Thread.stop()实现https://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html

 Caused by: java.lang.ThreadDeath
    at java.lang.Thread.stop(Thread.java:850)
    at com.ctsu.rdts.app.HttpDequeue.stopThread(HttpDequeue.java:944)
    at com.ctsu.rdts.app.HttpDequeue.clearLocks(HttpDequeue.java:418)
    at com.ctsu.rdts.app.HttpDequeue.run(HttpDequeue.java:404)
  

当受害者线程中抛出一个ThreadDeath实例   (不建议使用)调用Thread.stop()方法。

     

应用程序应仅在必须时才捕获此类的实例   异步终止后清理。如果是ThreadDeath   被一种方法捕获,重要的是它被重新抛出以便   线程实际上已经死了。

     

如果,顶级错误处理程序不会打印出消息   永远不会捕获ThreadDeath。