org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [select CNTR_EF_ID from ship_bill where bill_no = ?]; SQL state [null]; error code [17008]; 关闭的连接; nested exception is java.sql.SQLException: 关闭的连接
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:83)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:602)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:636)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:665)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:673)
at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:728)
at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:744)
at net.huadong.eservices.edi.action.DeliorAction.generateDeliorIFV(DeliorAction.java:180)
at sun.reflect.GeneratedMethodAccessor685.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.webbuilder.utils.SysUtil.executeMethod(SysUtil.java:55)
at com.webbuilder.controls.Method.descript(Method.java:11)
at com.webbuilder.controls.Control.create(Control.java:50)
at com.webbuilder.common.Parser.createControl(Parser.java:546)
at com.webbuilder.common.Parser.parseElements(Parser.java:462)
at com.webbuilder.common.Parser.parseElements(Parser.java:465)
at com.webbuilder.common.Parser.parse(Parser.java:165)
at com.webbuilder.common.Main.doGet(Main.java:193)
at com.webbuilder.common.Main.doPost(Main.java:266)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:643)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.resteasy.plugins.server.servlet.FilterDispatcher.doFilter(FilterDispatcher.java:63)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at net.huadong.port.lsmp.filter.LoginFilter.doFilter(LoginFilter.java:101)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:206)
at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:179)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at net.huadong.pass.core.platform.webService.WebServiceFilter.doFilter(WebServiceFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11NioProcessor.process(Http11NioProcessor.java:891)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:750)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:2282)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
JNDI配置如下:
<Resource name="jdbc/shjjhy"
auth="Container" type="javax.sql.DataSource"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@***"
username="***"
password="***"
testOnBorrow="true"
testWhileIdle="true"
testOnReturn="true"
validationQuery="select 1 from dual"
minEvictableIdleTimeMillis="10000"
timeBetweenEvictionRunsMillis="10000"
maxActive="500"
maxIdle="50"
maxWait="1000" removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true" initialSize="5" />
Spring的配置如下:
<bean id="dataSourceJNDI" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/shjjhy</value>
</property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
abstract="false" lazy-init="false">
<property name="dataSource">
<ref bean="dataSourceJNDI" />
</property>
</bean>
JDBCTemplate默认是使用的单例模式,在系统中我们是这样获取JDBCTemplate的:
WebApplicationContext ctx = (WebApplicationContext) request
.getAttribute("WebApplicationContext");
JdbcTemplate jt = (JdbcTemplate) ctx.getBean("jdbcTemplate");
基本上是所有只要使用JDBCTemplate进行数据操作的地方都会报错,我在后台监控也看到了,数据连接池最高的时候也就20个连接,而且关键就是在系统运行一段时间后才会出这个问题,时间不确定,有时候一两个星期出现,有时候一天出现两三次,每次都只能通过重启Tomcat来解决。
我想了好久,觉得最大的可能性是,JDBCTemplate在某个地方被强制关闭了,但是JDBCTemplate的Connection关闭我记得是自己处理的啊,所以我也不知道到哪里去找错误的根源,所以来请教各路大神!!!看各位是否遇到过这种情况;
我总结下:
1、一般都是系统在运行一段时间后才会报错,而且只要是使用JDBCTemplate的地方就会报错,如果是直接获取Connection来调用是不会报错的;
2、连接数最高不超过20,远远没有达到连接池的限制,如图:
3、每次都只能通过重启服务器解决此问题,是否有好的解决方案或者思路?
21 个解决方案
#1
这种现象一般是使用了关闭的Connection,
你仔细检查下代码是不是哪个地方使用了关闭的Connection操作了?
你仔细检查下代码是不是哪个地方使用了关闭的Connection操作了?
#2
感谢您的回复,就是这一点我很疑惑,JDBCTemplate中是自己封装了关闭数据库的连接,如何能让程序员显性的把JDBCTemplate中使用的Connection关闭呢?
#3
因为你是接手的项目,而不是你自己写的。
有些人在操作SQL时喜欢在程序里自己弄一个Connection进行操作.
而这个Connection是通过JDBCTemplate get到的,又进行了违规的操作.
至于为啥这么写...我觉得你应该去问问给你项目的那个人.
有些人在操作SQL时喜欢在程序里自己弄一个Connection进行操作.
而这个Connection是通过JDBCTemplate get到的,又进行了违规的操作.
至于为啥这么写...我觉得你应该去问问给你项目的那个人.
#4
大神,我在我的项目中搜索到了一段代码,麻烦您看下,是不是这样的就会出现这样的问题?
WebApplicationContext ctx = (WebApplicationContext) request.getAttribute("WebApplicationContext");
JdbcTemplate jt = (JdbcTemplate) ctx.getBean("jdbcTemplate");
Connection con = null;
try{
con = jt.getDataSource().getConnection();
con.setAutoCommit(false);
/**
* 业务操作
*/
con.setAutoCommit(true);
}catch(Exception e){
e.printStackTrace();
try {
con.setAutoCommit(true);
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
DbUtil.closeConnection(con, true);
}
然后上面的DbUtil.closeConnection(con, true);的方法如下:
public static boolean closeConnection(Connection connection,
boolean isExcept) {
/* 331 */boolean status = true;
try {
/* 333 */if ((connection != null) && (!connection.isClosed())) {
/* 334 */if (!connection.getAutoCommit())
try {
/* 336 */if (isExcept)
/* 337 */connection.rollback();
else
/* 339 */connection.commit();
} catch (Exception e) {
/* 341 */status = false;
/* 342 */if (!isExcept)
/* 343 */connection.rollback();
} finally {
/* 345 */connection.setAutoCommit(true);
}
/* 347 */connection.close();
/* 348 */connection = null;
}
} catch (Exception e) {
/* 351 */status = false;
}
/* 353 */return status;
}
再次感谢大神的指导!
#5
你找下 select CNTR_EF_ID from ship_bill where bill_no = ? 这个sql用的会话对象是怎么操作的,不行把这段代码删掉,测试下,会不会报错还.
#6
不需要显示关闭连接的
#7
一个可能的原因是,某个地方的连接没有关闭,导致连接被消耗光了。
#8
他这个不仅是这一个地方报错,是有很多地方都报错,我只是把其中一个错误贴出来而已,而且都是一些不相关的业务或者代码都只要用到了JDBCTemplate就会报错;
其中我拿出来的这个报错的地方是这样使用的:
String emptyBillSql = "select CNTR_EF_ID from ship_bill where bill_no = ?";
try {
WebApplicationContext ctx = (WebApplicationContext) request
.getAttribute("WebApplicationContext");
JdbcTemplate jt = (JdbcTemplate) ctx.getBean("jdbcTemplate");
for (String bill : bills) {
if (!StringUtil.isEmpty(bill)) {
bi = bill.split("-");
String billEFId = "F";
try {
billEFId = jt.queryForObject(emptyBillSql, new Object[]{bi[0]}, String.class);
} catch (Exception e) {
e.printStackTrace();
billEFId = "F";
}
// 以下代码省略
有的地方使用的是jt.queryForList 也一样的报错;就是那种突然就出现了,然后后台疯狂报错,全都是关闭的连接这样的错误。所以我也是怀疑是不是因为单例模式的影响,在某个地方把JDBCTemplate的连接关闭了,其他地方只要引用JDBCTemplate就都报错了。
但是我也不知道是什么样的代码能做到把JDBCTemplate的连接关闭而且让Spring不会新获取连接。
#9
我也查了很多资料是不应该显示的关闭连接;所以我也不确定下面这段代码是不是有问题,也不轻视是否会造成我前面说的那种情况出现:
WebApplicationContext ctx = (WebApplicationContext) request.getAttribute("WebApplicationContext");
JdbcTemplate jt = (JdbcTemplate) ctx.getBean("jdbcTemplate");
Connection con = null;
try{
con = jt.getDataSource().getConnection();
con.setAutoCommit(false);
/**
* 业务操作
*/
con.setAutoCommit(true);
}catch(Exception e){
e.printStackTrace();
try {
con.setAutoCommit(true);
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
DbUtil.closeConnection(con, true);
}
#10
一开始我也以为是这个原因,但是我的连接池设置了500的连接,这是很久以前以为是连接数的问题,所以设了这么大,但是我上面也给出了我们监控系统的图表,今天的最大连接数才19,但是今天就出现两次这样的问题, 我只能重启服务器才能解决。
#11
我建议你去检查下所有jdbc的代码(你们代码中所有的jdbc,不只是JDBCTemplate),你的现象和这个猜测很吻合。
ps: ctrl+shift+g 快捷键可以查看到所有引用。
#12
JdbcTemplate是spring封装的快速操作数据库的一套API,你可以点击进去看下源代码(这里就不提供了,没找到例子,这个东西已经被我们摒弃很多年了),肯定是不需要自己关闭的,而且后面看了下,WebApplicationContext ctx = (WebApplicationContext) request.getAttribute("WebApplicationContext");
JdbcTemplate jt = (JdbcTemplate) ctx.getBean("jdbcTemplate");
Connection con = null;
try{
con = jt.getDataSource().getConnection();
con.setAutoCommit(false);
/**
* 业务操作
*/
con.setAutoCommit(true);
}catch(Exception e){
e.printStackTrace();
try {
con.setAutoCommit(true);
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
DbUtil.closeConnection(con, true);
}
这块好像是要对事物做控制,不知道有AOP这个东西么,这块是线程安全的不,你的问题很可能是线程不安全导致
JdbcTemplate jt = (JdbcTemplate) ctx.getBean("jdbcTemplate");
Connection con = null;
try{
con = jt.getDataSource().getConnection();
con.setAutoCommit(false);
/**
* 业务操作
*/
con.setAutoCommit(true);
}catch(Exception e){
e.printStackTrace();
try {
con.setAutoCommit(true);
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
DbUtil.closeConnection(con, true);
}
这块好像是要对事物做控制,不知道有AOP这个东西么,这块是线程安全的不,你的问题很可能是线程不安全导致
#13
一个可能的原因是,某个地方的连接没有关闭,导致连接被消耗光了。
一开始我也以为是这个原因,但是我的连接池设置了500的连接,这是很久以前以为是连接数的问题,所以设了这么大,但是我上面也给出了我们监控系统的图表,今天的最大连接数才19,但是今天就出现两次这样的问题, 我只能重启服务器才能解决。
我建议你去检查下所有jdbc的代码(你们代码中所有的jdbc,不只是JDBCTemplate),你的现象和这个猜测很吻合。
ps: ctrl+shift+g 快捷键可以查看到所有引用。
也就是说如果jdbc的Connection是从JdbcTemplate里面取出来的话,再关闭是很有可能出现这种问题的?
#14
JdbcTemplate是spring封装的快速操作数据库的一套API,你可以点击进去看下源代码(这里就不提供了,没找到例子,这个东西已经被我们摒弃很多年了),肯定是不需要自己关闭的,而且后面看了下,WebApplicationContext ctx = (WebApplicationContext) request.getAttribute("WebApplicationContext");
JdbcTemplate jt = (JdbcTemplate) ctx.getBean("jdbcTemplate");
Connection con = null;
try{
con = jt.getDataSource().getConnection();
con.setAutoCommit(false);
/**
* 业务操作
*/
con.setAutoCommit(true);
}catch(Exception e){
e.printStackTrace();
try {
con.setAutoCommit(true);
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
DbUtil.closeConnection(con, true);
}
这块好像是要对事物做控制,不知道有AOP这个东西么,这块是线程安全的不,你的问题很可能是线程不安全导致
当时做这个项目的时候,并没有完全按照Spring的方式来做,就算JDBCTemplate老一点也没什么大问题,但问题就是,他们很多都是把JdbcTemplate转为原始的Connection后再操作,导致这个项目里面最少用了三种JDBC的操作,AOP更加没用上。
然后您说的关于线程的,这个方法并没有加任何synchronized的关键字来控制线程安全,然后我看了一下这段代码,然后也是我的疑惑所在,JdbcTemplate虽然是单例模式,但是不应该是每次我从Spring容器里面取一个JdbcTemplate出来的时候,应该就会向连接池要一个新连接对吧?如果是这样,就算这段代码里面我手动关闭了,应该也不会造成其他地方只要一调用JdbcTemplate就会报错吧?这样的话岂不是JDBCTemplate里面永远只有一个有效的连接?所有地方调用JdbcTemplate都是使用同一个Connection来操作的?
#15
你可以先把手动获取连接的代码先屏蔽,然后观察一段时间看看。
#16
没办法回答你那么详细来了,呵呵,这个东西N多年不用了,里面到底怎么运行的我也记不清楚了,有空你看下源码吧,或许能找到解决办法
#17
求助各位!!@ 楼上所有人!
经过几个月的查找问题,终于发现了原因所在,这个连接会丢失,是因为有人在Oracle数据库把Lock的Session给KILL掉了,只要有一个Session被KILL(即使是INACTIVE的Session),tomcat连接池就会报关闭的连接的错误!
所以求问各位大神,tomcat下的JNDI数据库连接池如何配置数据库连接重连的功能?
经过几个月的查找问题,终于发现了原因所在,这个连接会丢失,是因为有人在Oracle数据库把Lock的Session给KILL掉了,只要有一个Session被KILL(即使是INACTIVE的Session),tomcat连接池就会报关闭的连接的错误!
所以求问各位大神,tomcat下的JNDI数据库连接池如何配置数据库连接重连的功能?
#18
楼主你这个监控的工具是什么?谢谢告知
#19
楼主你这个监控的工具是什么?谢谢告知
javaMelody
要不要帮忙我看看这个问题啊,现在还没有解决。就是在数据库中KILL掉SESSION后,连接已经关闭了,但是tomcat认为还是有效的,继续放入连接池中了。。
#20
楼主你这个监控的工具是什么?谢谢告知
javaMelody
要不要帮忙我看看这个问题啊,现在还没有解决。就是在数据库中KILL掉SESSION后,连接已经关闭了,但是tomcat认为还是有效的,继续放入连接池中了。。
我也是遇到相似的问题了,不过我已经排除不是代码的问题了,你看看楼上的几位,要不就是连接池的配置问题。我也还在解决中。。
#21
后来我这里找了很久的错误,发现是因为有时候会有后台数据库死锁的情况,在数据库中KILL掉连接后,就会出现这样的问题;
这个连接池解决不了这个问题,只能优化系统代码,减少数据库死锁情况的出现。感谢这么多大神的关心与回复!
这个连接池解决不了这个问题,只能优化系统代码,减少数据库死锁情况的出现。感谢这么多大神的关心与回复!
#1
这种现象一般是使用了关闭的Connection,
你仔细检查下代码是不是哪个地方使用了关闭的Connection操作了?
你仔细检查下代码是不是哪个地方使用了关闭的Connection操作了?
#2
这种现象一般是使用了关闭的Connection,
你仔细检查下代码是不是哪个地方使用了关闭的Connection操作了?
感谢您的回复,就是这一点我很疑惑,JDBCTemplate中是自己封装了关闭数据库的连接,如何能让程序员显性的把JDBCTemplate中使用的Connection关闭呢?
#3
因为你是接手的项目,而不是你自己写的。
有些人在操作SQL时喜欢在程序里自己弄一个Connection进行操作.
而这个Connection是通过JDBCTemplate get到的,又进行了违规的操作.
至于为啥这么写...我觉得你应该去问问给你项目的那个人.
有些人在操作SQL时喜欢在程序里自己弄一个Connection进行操作.
而这个Connection是通过JDBCTemplate get到的,又进行了违规的操作.
至于为啥这么写...我觉得你应该去问问给你项目的那个人.
#4
因为你是接手的项目,而不是你自己写的。
有些人在操作SQL时喜欢在程序里自己弄一个Connection进行操作.
而这个Connection是通过JDBCTemplate get到的,又进行了违规的操作.
至于为啥这么写...我觉得你应该去问问给你项目的那个人.
大神,我在我的项目中搜索到了一段代码,麻烦您看下,是不是这样的就会出现这样的问题?
WebApplicationContext ctx = (WebApplicationContext) request.getAttribute("WebApplicationContext");
JdbcTemplate jt = (JdbcTemplate) ctx.getBean("jdbcTemplate");
Connection con = null;
try{
con = jt.getDataSource().getConnection();
con.setAutoCommit(false);
/**
* 业务操作
*/
con.setAutoCommit(true);
}catch(Exception e){
e.printStackTrace();
try {
con.setAutoCommit(true);
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
DbUtil.closeConnection(con, true);
}
然后上面的DbUtil.closeConnection(con, true);的方法如下:
public static boolean closeConnection(Connection connection,
boolean isExcept) {
/* 331 */boolean status = true;
try {
/* 333 */if ((connection != null) && (!connection.isClosed())) {
/* 334 */if (!connection.getAutoCommit())
try {
/* 336 */if (isExcept)
/* 337 */connection.rollback();
else
/* 339 */connection.commit();
} catch (Exception e) {
/* 341 */status = false;
/* 342 */if (!isExcept)
/* 343 */connection.rollback();
} finally {
/* 345 */connection.setAutoCommit(true);
}
/* 347 */connection.close();
/* 348 */connection = null;
}
} catch (Exception e) {
/* 351 */status = false;
}
/* 353 */return status;
}
再次感谢大神的指导!
#5
你找下 select CNTR_EF_ID from ship_bill where bill_no = ? 这个sql用的会话对象是怎么操作的,不行把这段代码删掉,测试下,会不会报错还.
#6
不需要显示关闭连接的
#7
一个可能的原因是,某个地方的连接没有关闭,导致连接被消耗光了。
#8
你找下 select CNTR_EF_ID from ship_bill where bill_no = ? 这个sql用的会话对象是怎么操作的,不行把这段代码删掉,测试下,会不会报错还.
他这个不仅是这一个地方报错,是有很多地方都报错,我只是把其中一个错误贴出来而已,而且都是一些不相关的业务或者代码都只要用到了JDBCTemplate就会报错;
其中我拿出来的这个报错的地方是这样使用的:
String emptyBillSql = "select CNTR_EF_ID from ship_bill where bill_no = ?";
try {
WebApplicationContext ctx = (WebApplicationContext) request
.getAttribute("WebApplicationContext");
JdbcTemplate jt = (JdbcTemplate) ctx.getBean("jdbcTemplate");
for (String bill : bills) {
if (!StringUtil.isEmpty(bill)) {
bi = bill.split("-");
String billEFId = "F";
try {
billEFId = jt.queryForObject(emptyBillSql, new Object[]{bi[0]}, String.class);
} catch (Exception e) {
e.printStackTrace();
billEFId = "F";
}
// 以下代码省略
有的地方使用的是jt.queryForList 也一样的报错;就是那种突然就出现了,然后后台疯狂报错,全都是关闭的连接这样的错误。所以我也是怀疑是不是因为单例模式的影响,在某个地方把JDBCTemplate的连接关闭了,其他地方只要引用JDBCTemplate就都报错了。
但是我也不知道是什么样的代码能做到把JDBCTemplate的连接关闭而且让Spring不会新获取连接。
#9
不需要显示关闭连接的
我也查了很多资料是不应该显示的关闭连接;所以我也不确定下面这段代码是不是有问题,也不轻视是否会造成我前面说的那种情况出现:
WebApplicationContext ctx = (WebApplicationContext) request.getAttribute("WebApplicationContext");
JdbcTemplate jt = (JdbcTemplate) ctx.getBean("jdbcTemplate");
Connection con = null;
try{
con = jt.getDataSource().getConnection();
con.setAutoCommit(false);
/**
* 业务操作
*/
con.setAutoCommit(true);
}catch(Exception e){
e.printStackTrace();
try {
con.setAutoCommit(true);
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
DbUtil.closeConnection(con, true);
}
#10
一个可能的原因是,某个地方的连接没有关闭,导致连接被消耗光了。
一开始我也以为是这个原因,但是我的连接池设置了500的连接,这是很久以前以为是连接数的问题,所以设了这么大,但是我上面也给出了我们监控系统的图表,今天的最大连接数才19,但是今天就出现两次这样的问题, 我只能重启服务器才能解决。
#11
一个可能的原因是,某个地方的连接没有关闭,导致连接被消耗光了。
一开始我也以为是这个原因,但是我的连接池设置了500的连接,这是很久以前以为是连接数的问题,所以设了这么大,但是我上面也给出了我们监控系统的图表,今天的最大连接数才19,但是今天就出现两次这样的问题, 我只能重启服务器才能解决。
我建议你去检查下所有jdbc的代码(你们代码中所有的jdbc,不只是JDBCTemplate),你的现象和这个猜测很吻合。
ps: ctrl+shift+g 快捷键可以查看到所有引用。
#12
JdbcTemplate是spring封装的快速操作数据库的一套API,你可以点击进去看下源代码(这里就不提供了,没找到例子,这个东西已经被我们摒弃很多年了),肯定是不需要自己关闭的,而且后面看了下,WebApplicationContext ctx = (WebApplicationContext) request.getAttribute("WebApplicationContext");
JdbcTemplate jt = (JdbcTemplate) ctx.getBean("jdbcTemplate");
Connection con = null;
try{
con = jt.getDataSource().getConnection();
con.setAutoCommit(false);
/**
* 业务操作
*/
con.setAutoCommit(true);
}catch(Exception e){
e.printStackTrace();
try {
con.setAutoCommit(true);
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
DbUtil.closeConnection(con, true);
}
这块好像是要对事物做控制,不知道有AOP这个东西么,这块是线程安全的不,你的问题很可能是线程不安全导致
JdbcTemplate jt = (JdbcTemplate) ctx.getBean("jdbcTemplate");
Connection con = null;
try{
con = jt.getDataSource().getConnection();
con.setAutoCommit(false);
/**
* 业务操作
*/
con.setAutoCommit(true);
}catch(Exception e){
e.printStackTrace();
try {
con.setAutoCommit(true);
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
DbUtil.closeConnection(con, true);
}
这块好像是要对事物做控制,不知道有AOP这个东西么,这块是线程安全的不,你的问题很可能是线程不安全导致
#13
一个可能的原因是,某个地方的连接没有关闭,导致连接被消耗光了。
一开始我也以为是这个原因,但是我的连接池设置了500的连接,这是很久以前以为是连接数的问题,所以设了这么大,但是我上面也给出了我们监控系统的图表,今天的最大连接数才19,但是今天就出现两次这样的问题, 我只能重启服务器才能解决。
我建议你去检查下所有jdbc的代码(你们代码中所有的jdbc,不只是JDBCTemplate),你的现象和这个猜测很吻合。
ps: ctrl+shift+g 快捷键可以查看到所有引用。
也就是说如果jdbc的Connection是从JdbcTemplate里面取出来的话,再关闭是很有可能出现这种问题的?
#14
JdbcTemplate是spring封装的快速操作数据库的一套API,你可以点击进去看下源代码(这里就不提供了,没找到例子,这个东西已经被我们摒弃很多年了),肯定是不需要自己关闭的,而且后面看了下,WebApplicationContext ctx = (WebApplicationContext) request.getAttribute("WebApplicationContext");
JdbcTemplate jt = (JdbcTemplate) ctx.getBean("jdbcTemplate");
Connection con = null;
try{
con = jt.getDataSource().getConnection();
con.setAutoCommit(false);
/**
* 业务操作
*/
con.setAutoCommit(true);
}catch(Exception e){
e.printStackTrace();
try {
con.setAutoCommit(true);
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
DbUtil.closeConnection(con, true);
}
这块好像是要对事物做控制,不知道有AOP这个东西么,这块是线程安全的不,你的问题很可能是线程不安全导致
当时做这个项目的时候,并没有完全按照Spring的方式来做,就算JDBCTemplate老一点也没什么大问题,但问题就是,他们很多都是把JdbcTemplate转为原始的Connection后再操作,导致这个项目里面最少用了三种JDBC的操作,AOP更加没用上。
然后您说的关于线程的,这个方法并没有加任何synchronized的关键字来控制线程安全,然后我看了一下这段代码,然后也是我的疑惑所在,JdbcTemplate虽然是单例模式,但是不应该是每次我从Spring容器里面取一个JdbcTemplate出来的时候,应该就会向连接池要一个新连接对吧?如果是这样,就算这段代码里面我手动关闭了,应该也不会造成其他地方只要一调用JdbcTemplate就会报错吧?这样的话岂不是JDBCTemplate里面永远只有一个有效的连接?所有地方调用JdbcTemplate都是使用同一个Connection来操作的?
#15
你可以先把手动获取连接的代码先屏蔽,然后观察一段时间看看。
#16
没办法回答你那么详细来了,呵呵,这个东西N多年不用了,里面到底怎么运行的我也记不清楚了,有空你看下源码吧,或许能找到解决办法
#17
求助各位!!@ 楼上所有人!
经过几个月的查找问题,终于发现了原因所在,这个连接会丢失,是因为有人在Oracle数据库把Lock的Session给KILL掉了,只要有一个Session被KILL(即使是INACTIVE的Session),tomcat连接池就会报关闭的连接的错误!
所以求问各位大神,tomcat下的JNDI数据库连接池如何配置数据库连接重连的功能?
经过几个月的查找问题,终于发现了原因所在,这个连接会丢失,是因为有人在Oracle数据库把Lock的Session给KILL掉了,只要有一个Session被KILL(即使是INACTIVE的Session),tomcat连接池就会报关闭的连接的错误!
所以求问各位大神,tomcat下的JNDI数据库连接池如何配置数据库连接重连的功能?
#18
楼主你这个监控的工具是什么?谢谢告知
#19
楼主你这个监控的工具是什么?谢谢告知
javaMelody
要不要帮忙我看看这个问题啊,现在还没有解决。就是在数据库中KILL掉SESSION后,连接已经关闭了,但是tomcat认为还是有效的,继续放入连接池中了。。
#20
楼主你这个监控的工具是什么?谢谢告知
javaMelody
要不要帮忙我看看这个问题啊,现在还没有解决。就是在数据库中KILL掉SESSION后,连接已经关闭了,但是tomcat认为还是有效的,继续放入连接池中了。。
我也是遇到相似的问题了,不过我已经排除不是代码的问题了,你看看楼上的几位,要不就是连接池的配置问题。我也还在解决中。。
#21
后来我这里找了很久的错误,发现是因为有时候会有后台数据库死锁的情况,在数据库中KILL掉连接后,就会出现这样的问题;
这个连接池解决不了这个问题,只能优化系统代码,减少数据库死锁情况的出现。感谢这么多大神的关心与回复!
这个连接池解决不了这个问题,只能优化系统代码,减少数据库死锁情况的出现。感谢这么多大神的关心与回复!