zoukankan      html  css  js  c++  java
  • 临时表的问题

    在做批量导入功能的时候,从页面导入excel文件,后台java程序读取文件内容存入一个List,然后将List数据做一些处理然后插入一张数据表,由于数据量较大,所以借助临时表,先将List做处理插入临时表,然后将临时表数据复制到要插入的数据表中。

    整个过程分这样几步:

    1.调用存储过程创建临时表

    2.java程序将读取的excel文件内容放入List,将List做处理然后插入到临时表(这个过程是在java程序里面做的)

    3.调用存储过程将临时表数据复制到要插入的数据表

    4.调用存储过程删除临时表

    思路是这样没错,但是实际操作的时候出现这样一个问题,创建临时表后,在后面的2、3、4步都随机性的报错临时表不存在。当时百思不得其解,因为公司另外一个项目里面也是这样做过的,功能一点问题也没有,后来我又仔细对比了两个项目的相关java代码,也没发现有什么不同,基本排除了java代码出问题的可能,那么就剩下数据连接的问题了,考虑到是不是数据连接池配置不同,然后又查看了数据连接池配置文件,果然,两个项目用的数据连接池是不同的,当前项目用的连接池是com.mchange.v2.c3p0.ComboPooledDataSource,原来那个项目用的连接池是org.apache.commons.dbcp.BasicDataSource,我把当前项目连接池配置修改成org.apache.commons.dbcp.BasicDataSource,重新测试就没有出现问题了

    
    
    <!-- 会报错的数据连接池配置 -->

    <!-- 加载数据库连接文件 -->
    <context:property-placeholder location="classpath:jdbc.properties" ignore-unresolvable="true" />
    <!-- 设置数据库连接池 -->
     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" parent="c3p0DataSource">
          <property name="driverClass" value="${jdbc.driver}" />
          <property name="jdbcUrl" value="${jdbc.url}" />
          <property name="user" value="${jdbc.username}" />
          <property name="password" value="${jdbc.password}" />
    </bean>
    <bean id="c3p0DataSource" abstract="true">
            初始化连接池中的连接数,取值应在minPoolSize与maxPoolSize之间,默认为3
            <property name="initialPoolSize" value="3" />
            连接池中保留的最小连接数,默认为:3
            <property name="minPoolSize" value="3" />
            连接池中保留的最大连接数。默认值: 15 
            <property name="maxPoolSize" value="1000" />
            最大空闲时间,*秒内未使用则连接被丢弃。若为0则永不丢弃。默认值: 0 
            <property name="maxIdleTime" value="60" />
            每360秒检查所有连接池中的空闲连接。默认值: 0,不检查
            <property name="idleConnectionTestPeriod" value="60" />
            定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个一显著提高测试速度。注意: 测试的表必须在初始数据源的时候就存在。Default: null 
            <property name="preferredTestQuery" value="select 1" />
            当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。默认值: 3
            <property name="acquireIncrement" value="5" />
            定义在从数据库获取新连接失败后重复尝试的次数。默认值: 30 ;小于等于0表示无限次
            <property name="acquireRetryAttempts" value="50" />
            重新尝试的时间间隔,默认为:1000毫秒   
            <property name="acquireRetryDelay" value="1000" />
            获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效 保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试 
            获取连接失败后该数据源将申明已断开并永久关闭。Default: false
            <property name="breakAfterAcquireFailure" value="false" />
            当连接池连接耗尽时,客户端调用getConnection()后等待获取新连接的时间,超时后将抛出SQLException,如设为0则无限期等待。单位毫秒。默认: 0
            <property name="checkoutTimeout" value="20000" />
             关闭连接时,是否提交未提交的事务,默认为false,即关闭连接,回滚未提交的事务  
            <property name="autoCommitOnClose" value="false" />
            Strongly disrecommended. Setting this to true may lead to subtle and bizarre bugs. (文档原文)作者强烈建议不使用的一个属性 
            <property name="forceIgnoreUnresolvedTransactions" value="false" />
            自动超时回收Connection
            <property name="unreturnedConnectionTimeout" value="1000" />
            c3p0全局的PreparedStatements缓存的大小。如果maxStatements与maxStatementsPerConnection均为0,则缓存不生效,只要有一个不为0,则语句的缓存就能生效。如果默认值: 0
            <property name="maxStatements" value="0" />
            maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。默认值: 0  
            <property name="maxStatementsPerConnection" value="0" />
            如果设为true那么在取得连接的同时将校验连接的有效性。Default: false 
            <property name="testConnectionOnCheckin" value="true" />
            因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的 时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable 
            等方法来提升连接测试的性能。Default: false 
            <property name="testConnectionOnCheckout" value="false" />
            早期的c3p0版本对JDBC接口采用动态反射代理。在早期版本用途广泛的情况下这个参数 允许用户恢复到动态反射代理以解决不稳定的故障。最新的非反射代理更快并且已经开始 
            广泛的被使用,所以这个参数未必有用。现在原先的动态反射与新的非反射代理同时受到 支持,但今后可能的版本可能不支持动态反射代理。Default: false 
            <property name="usesTraditionalReflectiveProxies" value="false" />
            c3p0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能 通过多线程实现多个操作同时被执行。Default: 3 
            <property name="numHelperThreads" value="5" />
    </bean>
    
    
    <!-- 修改后的数据连接池配置 -->

    <!-- 加载数据库连接文件 -->
        <context:property-placeholder location="classpath:jdbc.properties" ignore-unresolvable="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="100"></property>
            <property name="maxIdle" value="30"></property>
            <property name="maxWait" value="500"></property>
            <property name="defaultAutoCommit" value="true"></property>
    </bean>

    出现我这种问题,应该是这两种连接池本身对于临时表的机制不同,com.mchange.v2.c3p0.ComboPooledDataSource应该是在存储过程里面创建临时表,存储过程执行完就自动将临时表销毁了,而org.apache.commons.dbcp.BasicDataSource应该是在会话结束的时候才销毁临时表,不过这个只是个人猜想,没有经过验证,如果有哪位大神知道具体情况,麻烦评论里面告诉我一下

  • 相关阅读:
    maven之私服搭建
    maven之自定义archetype
    maven之自定义插件
    任务调度之 Elastic Job
    雪花算法原理解析
    基于 zxing 的二维码生成、解析
    spring-cloud-oauth2 认证授权
    spring security 自定义短信验证登录
    spring security session管理
    JDK1.8之HashMap实现原理
  • 原文地址:https://www.cnblogs.com/quyixuanblog/p/5318623.html
Copyright © 2011-2022 走看看