临时表的问题

时间:2022-09-08 09:05:04

在做批量导入功能的时候,从页面导入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应该是在会话结束的时候才销毁临时表,不过这个只是个人猜想,没有经过验证,如果有哪位大神知道具体情况,麻烦评论里面告诉我一下