• 基于struts2、spring的应用闲置一段时间后报空指针错(转)


    在做struts2、spring网站时,在系统闲置一段时间后,访问页面会出错,第二次再访问就正常了。后来查了后台日志,发现是数据库连接关闭了,导致页面访问出错。页面上报空指针错误,错误没有保留,日志中记录的错误如下:

    ERROR (java.sql.Connection:19)- Error calling Connection.close:
    java.sql.SQLException: Already closed.
    at org.apache.commons.dbcp.PoolableConnection.close(PoolableConnection.java:84)
    at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.close(PoolingDataSource.java:181)
    at org.springframework.jdbc.datasource.DataSourceUtils.doReleaseConnection(DataSourceUtils.java:313)
            at org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$TransactionAwareInvocationHandler.invoke(TransactionA
    wareDataSourceProxy.java:200)
            at $Proxy0.close(Unknown Source)
            at sun.reflect.GeneratedMethodAccessor58.invoke(Unknown Source)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
            at java.lang.reflect.Method.invoke(Method.java:585)
            at com.ibatis.common.jdbc.logging.ConnectionLogProxy.invoke(ConnectionLogProxy.java:68)
            at $Proxy1.close(Unknown Source)
            at com.ibatis.sqlmap.engine.transaction.external.ExternalTransaction.close(ExternalTransaction.java:82)
            at com.ibatis.sqlmap.engine.transaction.TransactionManager.end(TransactionManager.java:111)
            at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.endTransaction(SqlMapExecutorDelegate.java:782)
            at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.endTransaction(SqlMapSessionImpl.java:176)
            at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.endTransaction(SqlMapClientImpl.java:154)
            at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.autoEndTransaction(SqlMapExecutorDelegate.java:883)
            at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:622)
            at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:589)
            at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessionImpl.java:118)
            at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForList(SqlMapClientImpl.java:95)
            at com.wangar.ptc.dao.ibatis.IbatisSysMenuDAO.querySysMenuList(IbatisSysMenuDAO.java:50)
            at com.wangar.ptc.dao.impl.DefaultSysMenuDAO.querySysMenuList(DefaultSysMenuDAO.java:22)
            at com.wangar.ptc.manager.impl.DefaultSysMenuManager.querySysMenuList(DefaultSysMenuManager.java:187)
            at com.wangar.ptc.manager.impl.DefaultSysMenuManager.querySysMenuBySmid(DefaultSysMenuManager.java:146)
            at com.wangar.ptc.manager.impl.DefaultSysMenuManager.getRootSysMenu(DefaultSysMenuManager.java:90)
            at com.wangar.ptc.ao.impl.DefaultSysMenuAO.getRootSysMenu(DefaultSysMenuAO.java:50)
            at com.wangar.ptc.action.IndexAction.mainIndex(IndexAction.java:26)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
            at java.lang.reflect.Method.invoke(Method.java:585)
            at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:441)
            at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:280)
            at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:243)
            at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:165)
            at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
            at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
            at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:252)
            at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.jav
    a:68)

    ……省略部分错误……

    看到错误后大致想到了是因为数据连接长时间不用,自己关闭掉了,所以首先想到从数据源配置参数入手,经过一翻查找,看到有人遇到了和我一样的问题,在这里先把内容贴出来。我在spring中用apache 的 dbcp 数据进行数据库连接,配置代码如下:
    ####  DBCP配置 ####
    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/database
    jdbc.username=user
    jdbc.password=usr
    数据源配置
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    修改后的配置
    ####  DBCP配置 ####
    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/database
    jdbc.username=user
    jdbc.password=usr
    #初始化 连接
    jdbc.initialSize
    =0
    #连接池的最大活动个数
    jdbc.maxActive
    =20
    #没有人用连接的时候,最大闲置的连接个数。
    jdbc.maxIdle
    =100
    #没有人用连接的时候,最小闲置的连接个数。
    jdbc.minIdle
    =0
    #超时等待时间以毫秒为单位
    jdbc.maxWait
    =10000
    #是否自动回收超时连接
    jdbc.removeAbandoned
    =true
    #设置被遗弃的连接的超时的时间(以秒数为单位),即当一个连接被遗弃的时间超过设置的时间,则它会自动转换成可利用的连接。默认的超时时间是300秒。
    jdbc.removeAbandonedTimeout
    =60
    #是否在自动回收超时连接的时候打印连接的超时错误
    jdbc.logAbandoned 
    = true
    #给出一条简单的sql语句进行验证
    jdbc.validationQuery=select 1 from dual
    #在取出连接时进行有效验证
    jdbc.testOnBorrow=true


    数据源配置
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="maxActive" value="${jdbc.maxActive}" />
        <property name="maxIdle" value="${jdbc.maxIdle}" />
        <property name="maxWait" value="${jdbc.maxWait}" />
        <property name="removeAbandoned" value="${jdbc.removeAbandoned}" />
        <property name="removeAbandonedTimeout" value="${jdbc.removeAbandonedTimeout}" />
        <property name="logAbandoned" value="${jdbc.logAbandoned}" />
        <property name="validationQuery" value="${jdbc.validationQuery}" />
        <property name="testOnBorrow" value="${jdbc.testOnBorrow}" />
    </bean>

    其中蓝色加粗部分主要是解决数据库自动重连的问题。

    原文:http://blog.sina.com.cn/s/blog_655c5e7b0100h9iu.html

  • 相关阅读:
    持续交付知易行难,想做成这事你要理解这几个关键点
    运维需要懂产品和运营吗?
    云计算和AI时代,运维应该如何做好转型?
    从谷歌CRE谈起,运维如何培养服务意识?
    谷歌SRE运维模式解读
    如何打造好运维组织架构?
    如何在CMDB中落地应用的概念?
    有了CMDB,为什么还需要应用配置管理?
    Vue视图渲染原理解析,从构建VNode到生成真实节点树
    10个Vue开发技巧助力成为更好的工程师(二)
  • 原文地址:https://www.cnblogs.com/Anlycp/p/3302625.html
Copyright © 2020-2023  润新知