写点什么

浅析 MySQL JDBC 连接配置上的两个误区

  • 2017-03-26
  • 本文字数:2072 字

    阅读完需:约 7 分钟

相信使用 MySQL 的同学都配置过它的 JDBC 驱动,多数人会直接从哪里贴一段 URL 过来,然后稍作修改就上去了,对应的连接池配置也是一样的,很少有人会去细想这每一个参数都是什么含义。今天我们就来聊两个比较常见的配置——是否要开启autoReconnect和是否缓存PreparedStatement

一、autoReconnect=true真的好用么?

笔者看到过很多 MySQL 的 URL 里都是这样写的,复制过来改改 IP、端口和库名就能用了:

jdbc:mysql://xxx.xxx.xxx.xxx:3306/xxx?autoReconnect=true&...从字面上看挺好的,在连接断开后还会自动重连,加之 MySQL 有 8 小时自动断开连接的特性,在断开后连接会重连,多好的功能呀。但是如果你去阅读一下 MySQL Connect/J 开发手册的相关章节,就会看到官方是这么说明的:

The use of this feature is not recommended, because it has side effects related to session state and data consistency when applications don’t handle SQLExceptions properly, and is only designed to be used when you are unable to configure your application to handle SQLExceptions resulting from dead and stale connections properly.

简单来说,不推荐开启这个特性,因为有副作用,在没有正确处理SQLException时容易造成会话状态和数据一致性的问题。

一般的应用都会使用数据库连接池,那我们的连接池是否正确地处理了抛出的SQLException呢?抱着这个疑问,我们来看看阿里的 Druid 连接池是怎么处理的。

首先,通过设置合理的健康检查及连接存活时间能解决大部分问题;其次,它有针对特定异常的处理逻辑,在 MySqlExceptionSorter中会对特定返回码、异常类(比如com.mysql.jdbc.CommunicationsExceptioncom.mysql.jdbc.exceptions.jdbc4.CommunicationsException)以及错误消息进行处理,如果是致命错误就把连接抛弃。也就是说,如果用了 Druid,不管是否设置了autoReconnect,都能保证后续请求的正确处理。JBoss 的连接池实现也有类似的特性。

二、MySQL 是否真的不用打开 PSCache?

一般在设置连接池时,都会有类似下面的设置:

复制代码
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" />

很多文章上都说 PSCache 对使用游标的数据库有巨大的性能提升,但 MySQL 不建议开启,因为它不支持游标。所以很多人在用 MySQL 时,都会将poolPreparedStatements设置为false,就连 Druid 的文档上也是这么写的。

但事实真的是这样么,MySQL 使用 PSCache 真的对性能没有提升么?

先来看看关于游标的问题,其实大部分文章的表述不太准确,现在的 MySQL 在存储过程里是支持游标的,但其他地方的确不支持,具体详见官方手册(MySQL supports cursors inside stored programs.)。但这并不是我们要讨论的关键。

3.1.0 版本后的 JDBC 驱动里有一个参数是useServerPrepStmts,如果服务器支持的话,会开启服务端PreparedStatement,默认是false官方手册中有如下说明:

Server-side Prepared Statements - Connector/J 3.1 will automatically detect and use server-side prepared statements when they are available (MySQL server version 4.1.0 and newer).

也就是说在 MySQL 4.1.0 版本后,3.1.0 以上的驱动会检测到支持服务端PreparedStatement,并且启用该特性。根据 MySQLTUTORIAL 上的说明,整个过程分为 PREPAREEXECUTEDEALLOCATE PREPARE三步。MySQL JDBC 驱动的 Contributor Jess Balint StackOverflow 上做了一个详细的说明,《High-Performance Java Persistence》的作者也专门撰写文章分析了两者的区别。

复制代码
ps=conn.prepareStatement("select ?")
ps.setInt(1, 42)
ps.executeQuery()
ps.setInt(1, 43)
ps.executeQuery()

上述代码在使用客户端PreparedStatement时,MySQL 日志里看到的是:

复制代码
255 Query select 42
255 Query select 43

如果用的是服务端PreparedStatement,看到的则是(实际每次执行只会传占位符的值,语句是不传的):

复制代码
254 Prepare select ?
254 Execute select 42
254 Execute select 43

在整个使用过程中,Prepare 只会做一次,在这时服务端会对语句进行解析,后续收到具体值时会优化执行计划。如果同一条语句每次都新建PreparedStatement,那么每次都会多一回网络交互和语句解析,这显然是可以优化的。

综上所述,现在在使用 MySQL 时(如果版本比较新的话),出于性能考虑,应该在数据库连接池上开启针对PreparedStatement的缓存。如果没有使用连接池,或者所用的连接池不支持 PSCache,也可以在 JDBC 连接上设置cachePrepStmts=true

事实上,MySQL 的 JDBC 驱动还有不少针对性能的优化,比如设置useConfigs=maxPerformance(请酌情使用),相当于同时做了如下设置:

复制代码
cachePrepStmts=true
cacheCallableStmts=true
cacheServerConfiguration=true
useLocalSessionState=true
elideSetAutoCommits=true
alwaysSendSetIsolation=false
enableQueryTimeouts=false

各位同学,是时候检视一下自己的系统是如何连接 MySQL 的了,时代在发展,有些以前适用的配置也许就不再合适了。

2017-03-26 19:0011557
用户头像

发布了 135 篇内容, 共 62.8 次阅读, 收获喜欢 43 次。

关注

评论

发布
暂无评论
发现更多内容

〖产品思维训练白宝书 - 认知篇②〗- 破局高手都具备的一种底层认知就是产品思维

哈哥撩编程

#产品思维

网站上的视频资源被偷偷转载了...

为自己带盐

知识产权 ffmpeg HLS openssl

看我如何用定值 Cookie 实现反爬

华为云开发者联盟

爬虫 开发 华为云 华为云开发者联盟 企业号 4 月 PK 榜

统一观测丨使用 Prometheus 监控 Nginx Ingress 网关最佳实践

阿里巴巴云原生

阿里云 云原生 Prometheus

ES和MongoDB:一次别开生面的比较

Java你猿哥

数据库 mongodb elasticsearch ES API

喜讯!华秋电子荣获深圳市半导体行业协会优秀合作奖

华秋电子

Spring MVC 之 HttpMessageConverter

做梦都在改BUG

Java spring Spring MVC

开源轻量级 IM 框架 MobileIMSDK 的微信小程序端已发布!

JackJiang

网络编程 IM 即时通讯IM

架构训练营模块一作业

请叫我馒头哥丶

架构 架构实战营

硬核!GitHub置顶102W字Redis高手心法笔记

做梦都在改BUG

Java 数据库 redis 缓存 面试

北京国家会计学院副教授王亚星:智能会计和价值财务有力支撑企业高质量发展

用友BIP

软件测试/测试开发丨Docker 搭建Web服务器nginx

测试人

nginx Docker 软件测试 自动化测试 测试开发

LeaRun低代码开发平台 赋能企业快速落地BI大屏

力软低代码开发平台

2023 - Dubbo 谷歌编程之夏报名启动了!

阿里巴巴云原生

阿里云 云原生 dubbo

KgCaptcha验证码实现笔记

宙哈哈

Python html 验证码

CANN训练:模型推理时数据预处理方法及归一化参数计算

华为云开发者联盟

人工智能 华为云 华为云开发者联盟 企业号 4 月 PK 榜

三点几嚟,饮茶先啦!PaddleSpeech发布全流程粤语语音合成

飞桨PaddlePaddle

人工智能 机器学习 深度学习 语音识别

教你如何通过CodeArts IDE插件调用API,高效合成语音

华为云开发者联盟

云计算 开发 华为云 华为云开发者联盟 企业号 4 月 PK 榜

最强嘴替:新任技术管理者如何快速成长,完成转型逆袭?

LigaAI

技术管理 管理者 逆袭 技术人成长 企业号 4 月 PK 榜

数智时代的来临,养老行业接入人工智能技术已是势不可挡

加入高科技仿生人

人工智能 AI 养老服务 养老

PHP短信验证码防刷方案

宙哈哈

php html 图片验证码

KgCaptcha验证的那些事

宙哈哈

php Python html 验证码

2023 年“和鲸杯”辽宁省普通高等学校本科大学生计算机设计竞赛启动会顺利召开

ModelWhale

大数据 人才培养 数据科学 数据思维 数据竞赛

聊聊接口文档的事儿

京茶吉鹿

接口文档 Knife4j swagger2

强强携手促发展 中建信息成为麒麟软件全国总经销商

极客天地

# 架构实战营-模块1-作业

Geek_e948d4

没有设计师?没问题!Spring+OpenAI让你也能生成漂亮的图片!

Java你猿哥

Java spring maven API

华为云GaussDB践行数字化,护航证券保险高质量发展

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟 企业号 4 月 PK 榜

2023企业上云暨算云融合产业大会在京召开

中国IDC圈

算力 可信云

【送猫超卡、阿里云代金券】动手体验 SAE+云效 10 分钟快速打通 CI/CD 流水线

阿里巴巴云原生

阿里云 Serverless 云原生

浅析MySQL JDBC连接配置上的两个误区_数据库_丁雪丰_InfoQ精选文章