spring 无法打开事务的JDBC连接

2hh7jdfx  于 2023-03-07  发布在  Spring
关注(0)|答案(1)|浏览(173)

I would like to report a configuration problem that seems strange to me. Here's the application context configuration file I'm using

<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>

But when run the converting action, i have this error:
Problems with processing file /***.zip org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is 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.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:241) at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:372) at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:417) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:255) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) at com.sun.proxy.$Proxy5.processFile(Unknown Source) at ru.rt.mnp.translator.converter.job.ConvertTask.execute(ConvertTask.java:69) at sun.reflect.GeneratedMethodAccessor12.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:273) at org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:311) at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:113) at org.quartz.core.JobRunShell.run(JobRunShell.java:207) at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:560) Caused by: 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:189) at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:203)
Can anyone explain me what is the problem ? What should i do to fix this?
Thank you!

ljsrvy3e

ljsrvy3e1#

我不得不在一个使用SpringBoot的Web应用程序中使用SingleConnectionDataSource。我们也使用了一个ORM包来处理所有的数据库事务,即使suppressClose配置为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">

相关问题