谁实验过 jdbc 建立连接后不释放 并一直使用这个连接吗?

chichenzhe 2017-03-22 02:24:31
为啥jdbc默认写法 是 getconnction->use->close
而不是 getconnction only once-> use+use...

PreparedStatement可以释放,ResultSet也可以释放. 唯独connection一直占着(比如就像维持socket长连接这个概念).
connection 只在程序初始化的时候get一次, 随程序关闭而释放, 使用中的时候永远只有一个connection(或者自己写方法管理一个x个connection的连接池, x个连接永不释放). 这样为什么不行?

虽然在N多年以前我就知道这个传闻:
如果使用连接池的话,调用connection.close()是通知连接池回收该connection,不进行关闭操作。所以就回到池里了。关闭操作,由连接池在一定条件下执行的。连接池自己维护创建新链接、关闭长期不用链接等等。

但实际测试中我发现, 2个sql执行, 如果用一个connection 会比 用常规的getconnection+jdbcwork+close *2 要快接近一倍的时间.如果如我上面传闻的描述的话 那我这个测试中的耗时就不可能有这么大的差异.如果按上文传闻的描述, 用一个connection执行两个SQL动作应该等价于常规的getconnection+jdbcwork+close *2 但, 事实显然不是这样.

所以我就疑惑了, 是我JDBC配置文件设置有问题吗? 或是本身jdbc-connection.close就是真正的数据库 socket-close ?
...全文
4050 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
一线大码 2021-06-11
  • 打赏
  • 举报
回复

我现在也遇到这个问题,能理解楼主所说的,其他人的回答都在说连接资源的宝贵,所以要释放,但是如果我这个程序并不是要面对用户的,而是一个后台流式计算模块,可以理解为我这个程序会启动固定的10个线程,这10个线程会一直存在处理流式数据,但是中间每条数据我都需要访问数据库,所以我的需求也是要维持10个数据库连接,并且每个线程一直持有自己的一个数据库连接,直到程序关闭。所以总的数据库连接也就10个,不存在浪费的问题。这个楼主是怎么实现的?就是说怎么实现保持连接不关闭,在同一线程中还能复用的方法?

  • 打赏
  • 举报
回复
大家都说的是,数据库的链接是有限的如果不释放资源会宕机的这是系统最不想见到的亲好看,如果不释放资源会让系统访问越来越慢这个也是大家不想看到的,所资源一定要释放。
oh_Maxy 2017-03-24
  • 打赏
  • 举报
回复
引用 4 楼 chichenzhe 的回复:
[quote=引用 2 楼 yql1986 的回复:] 一般连接池的返回的connection都是一个代理对象,其内部的close操作实际上只是将其归还给连接池,连接池 会周期性的或每次执行命令时检测connection对象是否能跟数据库通信,如果不能话将其从数据库连接池中移除并 会将其关闭,因为connection关联了socket这一系统的资源,关闭connection就相当于释放系统资源(句柄之类)。 如果不使用连接池,直接close完就是相当关掉了socket,释放系统资源。
我写socket程序已经有很多年了, 算是对socket,网络编程比较了解. socket是否极其占用资源, 并且mysql的socket是否极其占用资源我还是知道的. 谢谢你介绍 connection, 但是这些知识在N年前我就已经掌握了. 我问题里说得很清楚: 我会get X个连接, 并且hold住(不释放). 这样测试的时候发现性能比 connection默认写法(getconnection+jdbcwork+close) 高很多. 这样我才产生了疑惑, 为什么大家通常使用的办法都是这种:
		} finally {
			try {
				if (pstm != null) {
					pstm.close();
					pstm = null;
				}
				if (conn != null) {
					conn.close();
					conn = null;
				}
			} catch (SQLException e) {
				Log.error("close conn is error", e);
			}
		}
实际上, 我手动get 50个连接,然后手动管理(包括心跳和超时断开重连) 的话性能应该是大家约定俗成的很多倍.[/quote] 因为这是教科书的写法:获取连接,使用,释放。我们平时使用数据库连接,都不会显式的获取连接,使用,关闭。而是依赖中间件获取连接,管理是否关闭连接,我们只需要关注业务代码部分的使用即可。 最后说一句,你同事这么教科书式的用了,如果没有什么特别的原因,你可以提出优化建议的。当然,人家听不听是另一回事啦!GL!
o枫叶o 2017-03-23
  • 打赏
  • 举报
回复
楼上说的很好,我补充一下:一个数据库允许的连接数量是有限的,如果你只申请不释放,很快就达到连接上线了,这时候其他人就无法访问数据库了。
yql1986 2017-03-23
  • 打赏
  • 举报
回复
一般连接池的返回的connection都是一个代理对象,其内部的close操作实际上只是将其归还给连接池,连接池 会周期性的或每次执行命令时检测connection对象是否能跟数据库通信,如果不能话将其从数据库连接池中移除并 会将其关闭,因为connection关联了socket这一系统的资源,关闭connection就相当于释放系统资源(句柄之类)。 如果不使用连接池,直接close完就是相当关掉了socket,释放系统资源。
yql1986 2017-03-23
  • 打赏
  • 举报
回复
不知道你想表达什么意思? 我给你讲解一下connection概念,希望对你用 首先connection是一个很宝贵的资源,其封装了socket。当执行数据库操作就是通过connection实质就是通过socket将sql语句发送到数据 库由数据库执行这些sql语句,这就是connection作用。 因为创建一个connection是很耗时的操作,一般使用连接池提前建立好一些connection,并让这些connection跟数据库一直保持能通信 这样就避免频繁的创建connection影响性能。 connection是一种资源,不使用的时候最好将其归还到连接池,如果一直占用这个connection也是可以的但是浪费资源,有可能别的地方要使用到connection.再说了数据库的最大连接数也是有限的。
chichenzhe 2017-03-23
  • 打赏
  • 举报
回复
引用 7 楼 hemowolf 的回复:
楼主的想法其实和连接池的设计思路是一样的,相当于自己实现一个连接池 楼上有人说了,用连接池的原因一方面是因为创建一个连接所消耗的时间比较长,另一方面是连接的数量有限制 在稍微大一点的系统中,连接池要面临的问题并不是一个普通的程序员甚至团队能够处理得好的。现成的连接池,人家各种问题都处理得很好,并且使用简单、开源免费,我何苦要自己实现一次呢! 至于说到的拿到连接就不释放,你要考虑多线程、多任务的场景,特别是在 WEB 开发这种断开式的请求
不好意思, 测试的源代码有问题, 不是我的代码, 拿的是同事已开发的东西和他之前写的连接池. 当我使用自己的连接池测试之后发现没有我描述的差异那么大(速度快接近一倍) 但是也有差异. 执行500次查询, 每次用我主题中描述的自实现的方式要快1毫秒以上. 即便是这个差异 也让我疑惑, 按理他们的差异应该在0.几毫秒 这种量级才对.
小灰狼 2017-03-23
  • 打赏
  • 举报
回复
楼主的想法其实和连接池的设计思路是一样的,相当于自己实现一个连接池 楼上有人说了,用连接池的原因一方面是因为创建一个连接所消耗的时间比较长,另一方面是连接的数量有限制 在稍微大一点的系统中,连接池要面临的问题并不是一个普通的程序员甚至团队能够处理得好的。现成的连接池,人家各种问题都处理得很好,并且使用简单、开源免费,我何苦要自己实现一次呢! 至于说到的拿到连接就不释放,你要考虑多线程、多任务的场景,特别是在 WEB 开发这种断开式的请求
o枫叶o 2017-03-23
  • 打赏
  • 举报
回复
引用 5 楼 chichenzhe 的回复:
[quote=引用 3 楼 u012964142 的回复:] 楼上说的很好,我补充一下:一个数据库允许的连接数量是有限的,如果你只申请不释放,很快就达到连接上线了,这时候其他人就无法访问数据库了。
不要人云亦云.并且注意审题. 我已经说了:"唯独connection一直占着(比如就像维持socket长连接这个概念).connection 只在程序初始化的时候get一次, 随程序关闭而释放" 因为只get一次 每次都使用此connection 那么也就不会出现你假想的:"如果你只申请不释放" . 所以也不会你假想的",很快就达到连接上线了"[/quote] 你这样是可以的,但有个致命缺点:数据库完全无法并发访问。你的connection对象不可能同时在两个方法里运行。这个效率影响估计能把用户气炸。
chichenzhe 2017-03-23
  • 打赏
  • 举报
回复
引用 3 楼 u012964142 的回复:
楼上说的很好,我补充一下:一个数据库允许的连接数量是有限的,如果你只申请不释放,很快就达到连接上线了,这时候其他人就无法访问数据库了。
不要人云亦云.并且注意审题. 我已经说了:"唯独connection一直占着(比如就像维持socket长连接这个概念).connection 只在程序初始化的时候get一次, 随程序关闭而释放" 因为只get一次 每次都使用此connection 那么也就不会出现你假想的:"如果你只申请不释放" . 所以也不会你假想的",很快就达到连接上线了"
chichenzhe 2017-03-23
  • 打赏
  • 举报
回复
引用 2 楼 yql1986 的回复:
一般连接池的返回的connection都是一个代理对象,其内部的close操作实际上只是将其归还给连接池,连接池 会周期性的或每次执行命令时检测connection对象是否能跟数据库通信,如果不能话将其从数据库连接池中移除并 会将其关闭,因为connection关联了socket这一系统的资源,关闭connection就相当于释放系统资源(句柄之类)。 如果不使用连接池,直接close完就是相当关掉了socket,释放系统资源。
我写socket程序已经有很多年了, 算是对socket,网络编程比较了解. socket是否极其占用资源, 并且mysql的socket是否极其占用资源我还是知道的. 谢谢你介绍 connection, 但是这些知识在N年前我就已经掌握了. 我问题里说得很清楚: 我会get X个连接, 并且hold住(不释放). 这样测试的时候发现性能比 connection默认写法(getconnection+jdbcwork+close) 高很多. 这样我才产生了疑惑, 为什么大家通常使用的办法都是这种:
		} finally {
			try {
				if (pstm != null) {
					pstm.close();
					pstm = null;
				}
				if (conn != null) {
					conn.close();
					conn = null;
				}
			} catch (SQLException e) {
				Log.error("close conn is error", e);
			}
		}
实际上, 我手动get 50个连接,然后手动管理(包括心跳和超时断开重连) 的话性能应该是大家约定俗成的很多倍.

62,634

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧