无法为事务打开JDBC连接

时间:2018-08-24 08:01:29

标签: java spring jdbc spring-jdbc

我想报告一个配置问题,这对我来说似乎很奇怪。 这是我正在使用的应用程序上下文配置文件

  <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <context:annotation-config/>

<bean id="propertyConfigurer"
      class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:jdbc.properties</value>
        </list>
    </property>
</bean>

<bean id="processingStratagyContainer" class="ru.rt.mnp.translator.converter.process.ProcessingStratagyContainer">
    <property name="fileProcessingStratagyMap">
        <map>
            <entry key="Port_Increment" value-ref="portIncrementProcessingStratagy"/>
            <entry key="Return_Increment" value-ref="returnIncrementProcessingStratagy"/>
            <entry key="Port_All" value-ref="portAllProcessingStratagy"/>
        </map>
    </property>
</bean>

<!--�������� ������������������ ������������������ ������������-->
<bean id="portIncrementProcessingStratagy"
      class="ru.rt.mnp.translator.converter.process.PortIncrementProcessingStratagy">
    <property name="rowSizeColumnPosition" value="11"/>
    <property name="columnBindings">
        <map>
            <!--first has index 0-->
            <entry key="1" value="number[java.lang.String]"/>
            <entry key="5" value="old_route[java.lang.String]"/>
            <entry key="6" value="new_route[java.lang.String]"/>
            <entry key="9" value="region_code[java.lang.String]"/>
            <entry key="10" value="port_date[java.util.Date]{yyyy-MM-dd'T'HH:mm:ssXXX}"/>
        </map>
    </property>
</bean>

<bean id="returnIncrementProcessingStratagy"
      class="ru.rt.mnp.translator.converter.process.ReturnIncrementProcessingStratagy">
    <property name="rowSizeColumnPosition" value="9"/>
    <property name="columnBindings">
        <map>
            <!--first has index 0-->
            <entry key="1" value="number[java.lang.String]"/>
            <entry key="5" value="old_route[java.lang.String]"/>
            <entry key="6" value="new_route[java.lang.String]"/>
            <entry key="7" value="region_code[java.lang.String]"/>
            <entry key="8" value="port_date[java.util.Date]{yyyy-MM-dd'T'HH:mm:ssXXX}"/>
        </map>
    </property>
</bean>

<bean id="portAllProcessingStratagy"
      class="ru.rt.mnp.translator.converter.process.PortAllProcessingStratagy">
    <property name="rowSizeColumnPosition" value="6"/>
    <property name="columnBindings">
        <map>
            <!--first has index 0-->
            <entry key="0" value="number[java.lang.String]"/>
            <entry key="3" value="new_route[java.lang.String]"/>
            <entry key="4" value="region_code[java.lang.String]"/>
            <entry key="5" value="port_date[java.util.Date]{yyyy-MM-dd'T'HH:mm:ssXXX}"/>
        </map>
    </property>
</bean>




<bean id="postProcessingStratagyContainer" class="ru.rt.mnp.translator.converter.postprocess.PostProcessingStratagyContainer">
    <property name="postProcessingStratagableMap">
        <map>
            <entry key="Port_Increment" value-ref="mnpTrfPartPostProcessingStratagy"/>
            <entry key="Return_Increment" value-ref="mnpTrfPartPostProcessingStratagy"/>
            <entry key="Port_All" value-ref="mnpTrfFullPostProcessingStratagy"/>
            <entry key="IncrementCounter" value-ref="incrementCounterPostProcessingStratagy"/>
            <entry key="HistoryRequestFull" value-ref="historyRequestFullPostProcessingStratagy"/>
            <entry key="HistoryRequestPart" value-ref="historyRequestPartPostProcessingStratagy"/>
        </map>
    </property>
</bean>


<bean id="mnpTrfPartPostProcessingStratagy"
      class="ru.rt.mnp.translator.converter.postprocess.MnpTrfPartPostProcessingStratagy" >
      <property name="placeInPostProcessingChain" value="1"/>
</bean>

<bean id="mnpTrfFullPostProcessingStratagy"
      class="ru.rt.mnp.translator.converter.postprocess.MnpTrfFullPostProcessingStratagy" >
    <property name="placeInPostProcessingChain" value="2"/>
</bean>

<bean id="incrementCounterPostProcessingStratagy"
      class="ru.rt.mnp.translator.converter.postprocess.IncrementCounterPostProcessingStratagy" >
    <property name="placeInPostProcessingChain" value="9"/>
</bean>

<bean id="historyRequestFullPostProcessingStratagy"
      class="ru.rt.mnp.translator.converter.postprocess.HistoryRequestFullPostProcessingStratagy" >
    <property name="placeInPostProcessingChain" value="4"/>
</bean>

<bean id="historyRequestPartPostProcessingStratagy"
      class="ru.rt.mnp.translator.converter.postprocess.HistoryRequestPartPostProcessingStratagy">
    <property name="placeInPostProcessingChain" value="3"/>
</bean>

<bean id="convertTask" class="ru.rt.mnp.translator.converter.job.ConvertTask"/>
<bean id="testTask" class="ru.rt.mnp.translator.converter.job.TestTask"/>
<bean id="historyRequestTask" class="ru.rt.mnp.translator.converter.job.HistoryRequestTask"/>

**<bean id="dataSource" class="org.springframework.jdbc.datasource.SingleConnectionDataSource">
    <property name="driverClassName" value="org.postgresql.Driver"/>
    <property name="url" value="${url}"/>
    <property name="username" value="****"/>
    <property name="password" value="****"/>
</bean>**

<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<bean id="mnpHistoryDao" class="ru.rt.mnp.translator.converter.storage.MnpHistoryDao">
    <property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <constructor-arg name="dataSource" ref="dataSource"/>
</bean>

<!-- specifing class and method that is going to be called on a specified
 time basis -->
<bean id="convertJob"
      class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    <property name="targetObject" ref="convertTask"/>
    <property name="targetMethod" value="execute"/>
</bean>

<bean id="convertTestJob"
      class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    <property name="targetObject" ref="testTask"/>
    <property name="targetMethod" value="execute"/>
</bean>

<bean id="historyRequestJob"
      class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    <property name="targetObject" ref="historyRequestTask"/>
    <property name="targetMethod" value="execute"/>
</bean>

<!-- simple trigger specify repeat interval and delay time -->
<bean id="cronTrigger"
      class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
    <property name="jobDetail" ref="convertJob"/>
    <!--<property name="cronExpression" value="0 5 0,2,4,6,8,10,12,14,16,18,20,22 ? * *"/>-->
    <property name="cronExpression" value="0 15,45 * ? * *"/>
    <property name="startDelay" value="1000"/>
</bean>


<bean id="cronTestTrigger"
      class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
    <property name="jobDetail" ref="convertTestJob"/>
    <property name="cronExpression" value="0 0/10 * ? * *"/>
    <property name="startDelay" value="1000"/>
</bean>

<bean id="cronHistoryRequestTrigger"
      class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
    <property name="jobDetail" ref="historyRequestJob"/>
    <property name="cronExpression" value="0/10 * * ? * *"/>
    <property name="startDelay" value="1000"/>
</bean>

<!-- scheduler factory bean to bind,the executing code and time intervals
 together -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="configLocation" value="classpath:quartz.properties"/>
    <property name="jobDetails">
        <list>
            <ref bean="convertJob"/>
            <ref bean="convertTestJob"/>
            <ref bean="historyRequestJob"/>
        </list>
    </property>
    <property name="triggers">
        <list>
            <ref bean="cronTrigger"/>
            <ref bean="cronTestTrigger"/>
            <ref bean="cronHistoryRequestTrigger"/>
        </list>
    </property>
</bean>

但是在执行转换操作时,出现此错误:

  

处理文件/***.zip的问题   org.springframework.transaction.CannotCreateTransactionException:   无法打开JDBC连接进行事务;嵌套异常为   java.sql.SQLException:连接已在中关闭   SingleConnectionDataSource。检查用户代码检查shouldClose()   关闭连接之前,或将“ suppressClose”设置为“ true”           在org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:241)           在org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:372)           在org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:417)           在org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:255)           在org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)           在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)           在org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)           位于com.sun.proxy。$ Proxy5.processFile(未知来源)           在ru.rt.mnp.translator.converter.job.ConvertTask.execute(ConvertTask.java:69)           在sun.reflect.GeneratedMethodAccessor12.invoke(未知来源)           在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)           在java.lang.reflect.Method.invoke(Method.java:497)           在org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:273)           在org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean $ MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:311)处           在org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:113)           在org.quartz.core.JobRunShell.run(JobRunShell.java:207)           在org.quartz.simpl.SimpleThreadPool $ WorkerThread.run(SimpleThreadPool.java:560)   引起原因:java.sql.SQLException:连接已在中关闭   SingleConnectionDataSource。检查用户代码检查shouldClose()   关闭连接之前,或将“ suppressClose”设置为“ true”           在org.springframework.jdbc.datasource.SingleConnectionDataSource.getConnection(SingleConnectionDataSource.java:189)           在org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:203)

任何人都可以解释我的问题吗? 我该怎么做才能解决此问题?

谢谢!

1 个答案:

答案 0 :(得分:0)

我不得不在使用 SpringBoot 的 Web 应用程序中使用 SingleConnectionDataSource。我们还为所有数据库事务使用了 ORM 包,即使将抑制关闭配置为 true,我也遇到了同样的问题。第一次登录的时候还可以,但是当连接长时间空闲时,就会出现下面的错误。

错误是

java.sql.SQLException: Connection was closed in SingleConnectionDataSource. Check that user code checks shouldClose() before closing Connections, or set 'suppressClose' to 'true'
    at org.springframework.jdbc.datasource.SingleConnectionDataSource.getConnection(SingleConnectionDataSource.java:167)

最后将数据源配置为会话范围的对象解决了它。之前是单例,将其重新配置为会话范围解决了问题。

<bean id="dataSource" class="org.springframework.jdbc.datasource.SingleConnectionDataSource"  scope="session">