Atomikos + druid 多数据源数据库连接超时回收问题怎么解决,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
创新互联公司坚持“要么做到,要么别承诺”的工作理念,服务领域包括:网站建设、做网站、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的湘潭县网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!
一段时间不查询数据,通常是过一夜第二天一早发起第一次连接时会出现数据库无法连接异常:
//通常会出现下面错误,异常情况一: com.MySQL.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 37,350,882 milliseconds ago. The last packet sent successfully to the server was 37,350,882 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem. //异常情况二: ERROR [com.alibaba.druid.pool.DruidPooledStatement:357] - CommunicationsException, druid version 1.1.10, jdbcUrl : jdbc:mysql://XX.XX.XX.XX:3306/txsmarthome?useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&noAccessToProcedureBodies=true&autoReconnect=true&failOverReadOnly=false&pinGlobalTxToPhysicalConnection=true, testWhileIdle true, idle millis 39540140, minIdle 50, poolingCount 0, timeBetweenEvictionRunsMillis 60000, lastValidIdleMillis 39540140, driver com.mysql.jdbc.Driver, exceptionSorter com.alibaba.druid.pool.vendor.MySqlExceptionSorter //异常情况三: java.sql.SQLException: connection holder is null
出现上述前两个异常是由于数据库连接超过mysql配置的 wait_timeout 时间,连接被mysql回收,但是 druid 连接池并不知道连接已被回收,因此报错。
连接池都有失败重连功能,druid的做法是在下一次请求连接数据库时,重连上一个异常的连接,所以之后的每次请求都是异常,直到池中所有连接都重连一次。即连续失败次数就是 minIdle 配置的数量。
如果连接多数据库情况,每个数据库的请求都会连接失败 minIdle 次。
spring: datasource: druid: db1: # 每隔1小时检查数据库连接是否有效,连接成功1分钟后开始计时 removeAbandonedTimeout: 3600 # 如果连接失效就删重连 removeAbandoned: true # 删除时输出日志 logAbandoned: true # 测试查询查询结果 testOnReturn: true
上述配置可保证限时删除无效连接。
命令行连接数据库后,执行:show global variables like "%timeout%";
mysql> show global variables like "%timeout%"; +-----------------------------+----------+ | Variable_name | Value | +-----------------------------+----------+ | connect_timeout | 10 | | delayed_insert_timeout | 300 | | have_statement_timeout | YES | | innodb_flush_log_at_timeout | 1 | | innodb_lock_wait_timeout | 7200 | | innodb_rollback_on_timeout | OFF | | interactive_timeout | 3600 | | lock_wait_timeout | 31536000 | | net_read_timeout | 30 | | net_write_timeout | 60 | | rpl_stop_slave_timeout | 31536000 | | slave_net_timeout | 60 | | wait_timeout | 3600 | +-----------------------------+----------+
上述数据库的链接有效时间是1小时,mysql默认为8小时,可使用命令修改,无须重启mysql:
# 修改为12小时,注意下面两个配置项要一致才能生效 mysql> set global interactive_timeout=43200; Query OK, 0 rows affected mysql> set global wait_timeout=43200; Query OK, 0 rows affected
需要注意 链接池 removeAbandonedTimeout <= 数据库 wait_timeout。
异常情况三的场景更复杂一些, atomikos 工作在 druid 上层,当druid检测到超时链接并重连后,并不会通知 atomikos,所以下次sql执行时仍然会报错。
atomikos 资料较少,看源码太费时,有空了再研究。
尽量增大数据库 wait_timeout 的时间(需要注意过大的 wait_timeout 会影响数据回收无效链接)。
可关闭druid removeAbandoned 功能。
配置一个定时器,在 min(wait_timeout,removeAbandonedTimeout) 时间内至少执行 minIdle 次,每次都在所有数据源中执行一个简单的查询。
三种方式可结合使用
升级 mysql-jdbc-driver 到6以上据说也可以解决,没有测试过。
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注创新互联行业资讯频道,感谢您对创新互联的支持。