Could not open JDBC Connection for transaction; nested exception is com.alibaba.druid.pool.DataSourc

  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

    一、错误概述

    项目中使用了阿里的 Druid 数据库刚开始很正常后来发现出现了问题问题如下

    org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is com.alibaba.druid.pool.DataSourceClosedException: dataSource already closed at Fri Jul 08 16:14:13 GMT+08:00 2022
        at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:309)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.startTransaction(AbstractPlatformTransactionManager.java:400)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:595)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:382)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698)
        at java.base/java.util.TimerThread.mainLoop(Timer.java:566)
        at java.base/java.util.TimerThread.run(Timer.java:516)
    Caused by: com.alibaba.druid.pool.DataSourceClosedException: dataSource already closed at Fri Jul 08 16:14:13 GMT+08:00 2022
        at com.alibaba.druid.pool.DruidDataSource.getConnectionInternal(DruidDataSource.java:1113)
        at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:1017)
        at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:997)
        at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:987)
        at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:103)
        at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:265)
        ... 13 common frames omitted

     日志比较多重点有以下几个

    Could not open JDBC Connection for transaction; nested exception is com.alibaba.druid.pool.DataSourceClosedException: dataSource already closed at Fri Jul 08 16:14:13 GMT+08:00 2022

     Caused by: com.alibaba.druid.pool.DataSourceClosedException: dataSource already closed at Fri Jul 08 16:14:13 GMT+08:00 2022

     其他的我们截图看看

     上图打码的地方是公司的dao层查数据库的代码。

    意思很明白了就是因为在进行查询的时候连接已经关闭了而且会一直刷出这样的日志。

    二、网友的给出的原因与解决方案

    综合网上大家的意见可能原因主要有以下几点

    1.异步线程问题

    你可能使用了异步线程去访问数据库异步线程是不由spring管理也就是说spring可以在异步线程未执行完就会进行容器关闭 当异步线程执行到获取数据库的时候就会报错

     博主给的答案是

    怎么才能彻底消除这个错误没有找到完美的解决方法只要DataSource不进行重新注册或者重新注册后再刷新相关的DAO引用的实例可暂时不出现这个问题了

     参考Druid连接池自动关闭

    2.多线程批量问题

    其实这个答案和上面一个的说法一致不过这个给出了解决方案

     多线程批量处理的时候只需要在service方法上加上@transactional(rollbackFor = Exception.class)就行了,mybatis就不会每次执行完sql后closing sql session了

    3. 热部署问题

    是否在定时器中手动获取了 DataSource然后使用后关闭了或者用完后长期不再用被连接池自动关闭了

    答案是发现不修改代码的时候不会发生异常修改代码之后触发热加载然后就中断了链接所以就报出那个错误。

    这是网友的答案。

    4.自动关闭问题

    应该就是长时间不用Druid自动关闭的问题。

    这也是网友给出的可能性答案。

    下面的也是网友的答案

    如果使用 jfinal 提供的 ActiveRecord 或者 Db + Record 操作数据库就不会出现此问题自行得到 DataSource 或 Connection 的代码就需要开发者自己管理好这两个对象。

    这个我没有尝试。

    .setTestOnBorrow(false)
    .setTestOnReturn(false)

    都改成 true。有网友说这个答案。

    我试了试没有什么卵用。

    三、我的错误原因

    最终我发现可能的原因是

    我这项目启动的时候会有 @PostConstruct 注解初始化 redis 数据通过多线程方式去处理然后还会有定时任务定时刷新。而项目中有热部署只要改动代码之后就会自动重启项目然后就会出现了上述的错误。

    如果我改动了代码不让它热部署启动我手动重启或者先关闭项目然后再启动就不会报这个错误了。

    所以我这边最终的原因就是热部署的问题我的热部署不是使用的devtools而是idea上有一个配置改动配置之后就会热部署但是我忘记改动哪个地方了。以后想起来了再来修改文章。

    四、奇怪的问题

    我们同一套代码都是Git上最新代码但是我同事的代码就会报上面这个错误我的就好的他的没有热部署。最终发现的原因竟然是

    package com.xxx.common.util;
    
    import com.xxx.common.file.SftpAuthority;
    import com.xxx.ytec.common.file.SftpService;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
    
    @Component
    @Order(1)
    public class FileCommandLineRunner implements CommandLineRunner {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(FileCommandLineRunner.class);
    
        @Autowired
        private SftpService sftpService;
    
        @Override
        public void run(String... args) throws Exception {
            LOGGER.info("---------FileCommandLineRunner下载文件开始---------");
    
            SftpAuthority root = new SftpAuthority("root", "192.168.0.100", 22);
            root.setPassword("123456");
            sftpService.createChannel(root);
            sftpService.downloadFile(root, "/xxx/file/Data.csv", "C:\\Users\\Data.csv");
            LOGGER.info("---------FileCommandLineRunner下载文件成功---------");
        }
    }

     因为这一套代码他那里报了我们上面说的错这个代码怎么与数据源连接有关呢这个代码就是在项目启动的时候自动执行里面的代码里面的逻辑就是通过sftp从服务器上下载文件的。

    现在他的报错如下

     这个问题是很奇怪的在我的电脑上没问题在他那就会报错只好把这个代码注释掉了。本来这个代码是我写给他测试下载文件的也不会用到。

    问题不算完美解决暂时先这样吧

  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

    “Could not open JDBC Connection for transaction; nested exception is com.alibaba.druid.pool.DataSourc” 的相关文章