前几天同事做的一个安卓项目,我协助他搭建服务端工程,ORM框架使用mybatis-3.1.0,mvc框架使用的spring mvc(3.2.13.RELEASE),数据库为Oracle11G。

        项目是非常简单,直连数据库查询。刚开始SqlSessionFactory是自己写的,包括SqlSession 也是自己创建和释放。一切都很完好,自己测试OK,联调OK。(公司环境为JDK1.6,服务器为redhat)

        放到现场后问题来了(现场环境为JDK1.6,服务器为windows server,DB服务器为redhat):

        奇特现象一、每次APP启动的时候,去访问后端,后端第一次查询数据库,总会报一个奇怪的socket read timed out,第二次访问就好了。

        奇特现象二、APP有一段时间不操作(间隔时间不定),再次点击APP进行操作,也会报这个异常。

        接到现场反馈以后,第一反映是网络问题。但是两个服务器之间的网络确实没问题。于是开始爬坑,

    首先:去配置mybatis自带的envirment中的 

  <environments default="development">
        <environment id="development">
            <transactionManager type="jdbc" />
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}" />
                <property name="url" value="${jdbc.url}" />
                <property name="username" value="${jdbc.username}" />
                <property name="password" value="${jdbc.password}" />
                <!-- 新加 -->
                <property name="poolMaximumCheckoutTime" value="20000"/>
                <property name="poolPingQuery" value="SELECT 1 FROM DUAL" />
                <property name="poolPingEnabled" value="true" />
                <property name="poolPingConnectionsNotUsedFor" value="60000" />
                <!-- 新加结束 -->
            </dataSource>
        </environment>
    </environments>

     启动项目却被莫名其妙告知,我用的DataSource是UnpooledDataSource。

     本着现场事故大于天的心里,删掉了自己写的SqlSessionFactory,加入了高大上mybatis-spring-1.1.0和C3P0数据库连接池。然后重新发往现场,这时C3P0 配置如下:

        <!-- 配置数据源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <property name="driverClass" value="${KEY_DB_DRIVER_PM}" />
        <property name="jdbcUrl" value="${KEY_DB_URL_PM}" />
        <property name="user" value="${KEY_DB_USERNAME_PM}" />
        <property name="password" value="${KEY_DB_PASSWORD_PM}" />
        <!--连接池中保留的最大连接数。默认值: 15 -->
        <property name="maxPoolSize" value="25" />
        <!-- 连接池中保留的最小连接数,默认为:3 -->
        <property name="minPoolSize" value="10" />
        <!-- 初始化连接池中的连接数,取值应在minPoolSize与maxPoolSize之间,默认为3 -->
        <property name="initialPoolSize" value="10" />
    </bean>

没想到问题更加严重了,出现该问题的频率变大了。后来再次调整最后配置如下:

    <!-- 配置数据源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <property name="driverClass" value="${KEY_DB_DRIVER_PM}" />
        <property name="jdbcUrl" value="${KEY_DB_URL_PM}" />
        <property name="user" value="${KEY_DB_USERNAME_PM}" />
        <property name="password" value="${KEY_DB_PASSWORD_PM}" />
        <!--连接池中保留的最大连接数。默认值: 15 -->
        <property name="maxPoolSize" value="25" />
        <!-- 连接池中保留的最小连接数,默认为:3 -->
        <property name="minPoolSize" value="10" />
        <!-- 初始化连接池中的连接数,取值应在minPoolSize与maxPoolSize之间,默认为3 -->
        <property name="initialPoolSize" value="10" />
        <!–
              当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出
              SQLException,如设为0则无限期等待。单位毫秒。Default: 0
         –>
        <property name="checkoutTimeout" value="5000"/>
        <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
        <property name="maxIdleTime" value="60"/>
        <!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
        <property name="idleConnectionTestPeriod" value="60"/>
    </bean>

同时还对tomcat并发数做了调整。重启后至今为发现再次出现。