返回信息流rt,在springmvc的项目中使用jdbcTemplate操作数据库,执行update语句后,数据能正常入库,这个时候执行mysql> show status like 'Threads_connected';会发现,数据库连接加1,理论上请求处理完成后,jdbcTemplate不是会自动释放连接么?
这之后,一直执行插入后,当次数达到<property name="maxActive" value="10"/>后,再插入就报错了,提示数据库连接已满。。。
附代码
1、前10次正常,之后插入提示连接已满,Threads_connected一直不变,除非停止服务器,强制断开与mysql的连接
2、手动关闭各种资源,小并发下插入正常,Threads_connected在请求期间会一直变动,请求结束时,会恢复之前的值
这是一条镜像帖。来源:北邮人论坛 / java / #44459同步于 2015/9/28
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
[问题]求助jdbcTemplate释放连接的问题
dragontwf
2015/9/28镜像同步11 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
显然,看这里……(你竟然截图……害得我不能剪切粘贴……论坛明明有语法高亮的……)
createPreparedStatement函数给你传了一个Connection做参数(con),那就是Spring帮你创建的Connection,spring会帮你关掉的。你应该使用这个连接。
但是在这个函数题里,你又去getJDBCTemplate().getDataSource().getConnection(),你自己又创造了一个连接。你不应该再创造这个连接。就是因为这个Connection没有被关闭,导致出问题的。
暖神,请收下我的膝盖orz,结贴散花~~~
【 在 nuanyangyang 的大作中提到: 】
: 显然,看这里……(你竟然截图……害得我不能剪切粘贴……论坛明明有语法高亮的……)
: createPreparedStatement函数给你传了一个Connection做参数(con),那就是Spring帮你创建的Connection,spring会帮你关掉的。你应该使用这个连接。
: 但是在这个函数题里,你又去getJDBCTemplate().getDataSource().getConnection(),你自己又创造了一个连接。你不应该再创造这个连接。就是因为这个Connection没有被关闭,导致出问题的。
: ...................
【 在 dragontwf 的大作中提到: 】
: 暖神,请收下我的膝盖orz,结贴散花~~~
:
要不要试试java 1.8的lambda表达式呢?我觉得挺直观的,更难以犯错误,碰巧spring大量使用“只有一个方法的接口”,lambda正好用在spring上:这个例子从spring的文档里复制的,其实我并不知道是什么意思(羞)。
JdbcTemplate jdbcTemplate = ......
final String INSERT_SQL = "insert into my_test (name) values(?)";
final String name = "Rob";
KeyHolder kh = new GeneratedKeyHolder();
jdbcTemplate.update((conn) -> {
PreparedStatement ps = conn.prepareStatement(INSERT_SQL, new String[] { "id" });
ps.setString(1, name);
return ps;
}, kh);
虽然不懂springmvc 不过看这个代码,传递的con参数应该是在update函数里面由springmvc负责"手动"关闭,但是垃圾回收机制不会关闭lz以及获取的connection是吗
【 在 nuanyangyang (暖羊羊) 的大作中提到: 】
: 显然,看这里……(你竟然截图……害得我不能剪切粘贴……论坛明明有语法高亮的……)
: createPreparedStatement函数给你传了一个Connection做参数(con),那就是Spring帮你创建的Connection,spring会帮你关掉的。你应该使用这个连接。
: ...................
赞,回头研究下,正打算看看1.8呢。
【 在 nuanyangyang 的大作中提到: 】
:
: 要不要试试java 1.8的lambda表达式呢?我觉得挺直观的,更难以犯错误,碰巧spring大量使用“只有一个方法的接口”,lambda正好用在spring上:这个例子从spring的文档里复制的,其实我并不知道是什么意思(羞)。
: [code=java]
: ...................
【 在 Lamperouge 的大作中提到: 】
: 虽然不懂springmvc 不过看这个代码,传递的con参数应该是在update函数里面由springmvc负责"手动"关闭,但是垃圾回收机制不会关闭lz以及获取的connection是吗
嗯。spring会在执行完sql之后帮用户调用connection.close(),但垃圾回收不会关闭非内存的资源,比如文件、数据库连接等。
非内存资源怎么理解,比如一个Cursor没有close,但是这个Cursor,也是一个对象,有引用,引用为0不会处理吗?还是他有一个特殊的标志。
【 在 nuanyangyang (暖羊羊) 的大作中提到: 】
: 嗯。spring会在执行完sql之后帮用户调用connection.close(),但垃圾回收不会关闭非内存的资源,比如文件、数据库连接等。
【 在 icyfox 的大作中提到: 】
: 非内存资源怎么理解,比如一个Cursor没有close,但是这个Cursor,也是一个对象,有引用,引用为0不会处理吗?还是他有一个特殊的标志。
:
“引用计数”是非常慢的内存管理方式。高性能的JVM一般使用基于tracing的垃圾回收。也就是只有当GC认为内存不够的时候,才开始GC,然后才扫描一遍整个heap,然后把不可达的对象回收掉。
Java有finalizer,一般用来“紧急”关闭资源。JLS上说,这个函数会在“一个对象占用的空间被回收的时候调用”,但并没有说程序退出之前所有的空间都要回收。所以有可能finalizer永远不被调用。即使调用了,也许也是最后一个引用消失之后很久的事。所以finalizer是一种亡羊补牢的措施,可以减少“不及时关闭资源”造成的影响,但损失可能已经造成了。
因为这个原因,以前Python2.5很流行的写法
txt = open("somefile").read()
会在Jython里导致文件不及时关闭,因为垃圾回收不知道什么时候会执行,甚至不保证程序退出之前会执行。所以Python2.6开始,以及Jython里面,应该是:
with open("somefile") as f: # with块结束后自动关闭
txt = f.read()
cursor = null;
//cursor.close();
这样的操作,tracing不到原来的对象了,但是数据库还连接着,内存无法回收?
【 在 nuanyangyang (暖羊羊) 的大作中提到: 】
: “引用计数”是非常慢的内存管理方式。高性能的JVM一般使用基于tracing的垃圾回收。也就是只有当GC认为内存不够的时候,才开始GC,然后才扫描一遍整个heap,然后把不可达的对象回收掉。
: Java有finalizer,一般用来“紧急”关闭资源。JLS上说,这个函数会在“一个对象占用的空间被回收的时候调用”,但并没有说程序退出之前所有的空间都要回收。所以有可能finalizer永远不被调用。即使调用了,也许也是最后一个引用消失之后很久的事。所以finalizer是一种亡
: 因为这个原因,以前Python2.5很流行的写法
: ...................