连接池、ORA-00020以及编码习惯的问题

这两天手下的项目经理病休了,其他人又不能很快接手,只好自己顶上作一些很久没有干过的具体工作了。干多了,还是有一些感慨的。

其中一个很深刻的体会就是:编码的习惯真的很重要。

比如:在我们的一个项目中,在一个功能模块中,要上线了,开始做贝塔测试了,发现系统在工作一段时间之后就会出现莫名其妙的错误。比如:点击一个链接之后没有任何反应,控制台没有任何异常。

程序员们分析了很久,仍然是一头雾水。我也是在客户身边,打开自己的程序员写的代码开始分析。压力很大。

认真分析之后,发现很多问题。其中,导致这个问题的,应该是从连接池获取数绝库连接之后没有归还。造成数据库连接池中没有数据库连结可用,还有就是获取到statement之后,也没有相应位置关闭这些语句,造成oracle的游标打开过多,最终耗尽资源,而停止服务。

此外,在try catch到系统异常之后,没有任何处理,甚至没有一个e.printStackTrace(),这样造成系统没有任何提示。

这些问题,其实都是编程习惯的问题,看似很小的问题,但是正是这些很小的问题,会让你在客户面前颜面扫地。所以,细节决定成败!这就是一个非常贴切的例证。

说了这么多,有点跑出技术的题外了。下面把网上找到的一个参考资料与大家共享一下吧。



  很多朋友在Java开发中,使用Oracle数据库的时候,经常会碰到有ORA-01000: maximum open cursors exceeded.的错误。
  实际上,这个错误的原因,主要还是代码问题引起的。
  ora-01000: maximum open cursors exceeded.
  表示已经达到一个进程打开的最大游标数。
  这样的错误很容易出现在Java代码中的主要原因是:Java代码在执行conn.createStatement()和conn.prepareStatement()的时候,实际上都是相当与在数据库中打开了一个cursor。尤其是,如果你的createStatement和prepareStatement是在一个循环里面的话,就会非常容易出现这个问题。因为游标一直在不停的打开,而且没有关闭。
  一般来说,我们在写Java代码的时候,createStatement和prepareStatement都应该要放在循环外面,而且使用了这些Statment后,及时关闭。最好是在执行了一次executeQuery、executeUpdate等之后,如果不需要使用结果集(ResultSet)的数据,就马上将Statment关闭。
  对于出现ORA-01000错误这种情况,单纯的加大open_cursors并不是好办法,那只是治标不治本。实际上,代码中的隐患并没有解除。
  而且,绝大部分情况下,open_cursors只需要设置一个比较小的值,就足够使用了,除非有非常特别的要求。
  ---
  如果你不使用连接池,那么就没有什么问题,一旦Connection关闭,数据库物理连接就被释放,所有相关Java资源也可以被GC回收了。
  但是如果你使用连接池,那么请注意,Connection关闭并不是物理关闭,只是归还连接池,所以PreparedStatement和ResultSet都被持有,并且实际占用相关的数据库的游标资源,在这种情况下,只要长期运行,往往就会报“游标超出数据库允许的最大值”的错误,导致程序无法正常访问数据库。
  ---
  这个关不关和使用不使用conn pool没有关系,一般操作是会是这样,线程从外界获取一个conn,然后创建自己地stmt,rs,然后执行逻辑操作,然后将conn返回给pool。 如果程序员忘记手动关地话。当这个线程执行完以后,stmt,rs都成垃圾,当他们被垃圾搜集地时候,gc会替我们把它们给关闭地。这就是很多代码没有关闭,仍然正常运行。
  但是这样会有一个潜在地问题。就是gc无法确定什么时候运行。如果free地内存很多,很可能有些gc就不会被启动,这样stmt迟迟没有被关闭,执行一段时间会报错。
  所以健壮地代码应该手工把rs,stmt都关闭
  ---
  Java连结Oracle常犯错误
  1。只懂 createStatement,不懂关闭statement
  2.。只懂 createStatement,不懂preparedStatement.
  3 。只懂在sql里用to_date,甚至直接用String,不懂用 setDate()
  ---
  我记得.我的程序中也出现过这种问题,
  主要原因是我get Connection 对象后,这个connectin没有被进行关闭,
  同时进行出来的 preparedStatement 对象,不关闭也会出现这种问题,
  而且,推荐这些数据库操作的变量尽量用局部变量,现用现取,随时关闭,而且放在finally{}中进行关闭,

时间: 2024-10-13 17:19:40

连接池、ORA-00020以及编码习惯的问题的相关文章

编码错误-连接池数据源的配置文件错误

问题描述 连接池数据源的配置文件错误 <?xml version="1.0" encoding="UTF-8"?> type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000" username="HUANGZHIHAO" password="123456&quo

HttpClient连接池的连接保持、超时和失效机制

HTTP是一种无连接的事务协议,底层使用的还是TCP,连接池复用的就是TCP连接,目的就是在一个TCP连接上进行多次的HTTP请求从而提高性能.每次HTTP请求结束的时候,HttpClient会判断连接是否可以保持,如果可以则交给连接管理器进行管理以备下次重用,否则直接关闭连接.这里涉及到三个问题: 1.如何判断连接是否可以保持? 要想保持连接,首先客户端需要告诉服务器希望保持长连接,这就是所谓的Keep-Alive模式(又称持久连接,连接重用),HTTP1.0中默认是关闭的,需要在HTTP头加

tomcat连接池和mysql数据库的中文乱码

问题描述 Class.forName("com.mysql.jdbc.Driver");con = DriverManager.getConnection("jdbc:mysql://localhost:3306/java101_microblog?useUnicode=true&characterEncoding=UTF-8", "root", "2321456zlq");这样的方式获取连接,中文是没有乱码问题的~

ODP.NET连接池释放问题

问题描述 大牛们:关于使用odp.net连接操作oracle数据库时连接的释放问题,请教大家,问题如下:连接串:DataSource=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=filesynctest2)(PORT=1521))(CONNECT_DATA=(SID=filesync1)));UserId=xjliu;Password=111111;MaxPoolSize=10;MinPoolSize=1;问题:在默认使用连接池的情况下,程序在查询或操作数

连接池-关于Java服务长时间运行出现各种bug问题,可能运行几天没问题,但是运行十几天就会出现各种bug

问题描述 关于Java服务长时间运行出现各种bug问题,可能运行几天没问题,但是运行十几天就会出现各种bug 服务使用的是ScheduledThreadPoolExecuto定时任务,有使用到全局变量,数据库连接池使用的是c3p0,我感觉出现问题的原因可能就是这三个里哪个导致的,程序是没问题的,就是运行久了就出现各种问题了,而且很莫明奇妙,比如本来是好好的运行久了日志中的中文从那个时刻起往后全都乱码了.请问这是怎么回事? 定时任务: ScheduledThreadPoolExecutor boo

c3p0连接池中获取的Connection对象的close()方法是真的把连接给关闭了?

问题描述 c3p0连接池中获取的Connection对象的close()方法是真的把连接给关闭了? 自己做写了一个管理数据源的DBManager,构想中从数据源里面获取的Connection使用完之后执行close()方法,然后把Connection对象闲置回连接池中. 但是测试出来的结果好像每次执行close()之后connection就销毁了. 代码如下: DBManager.java package ben.DBUtils; import java.sql.Connection; impo

Netty的http client连接池设计

1 复用类型的选型 1.1 channel 复用 多个请求可以共用一个channel 模型如下:                                                特点: callback队列为回调队列. 不同的callback通过一个全局的id进行标识.发送的时候会把该id发到服务端,服务端在回复的时候必须把该id再返回到客户端. 获取连接只需要随机获取一个channel即可,将callback添加到队列里面.  获取连接时消除了锁的竞争,性能高效. 结构简单.  

使用tomcat5.0自带的连接池

近来对连接池产生了兴趣,就自己动手试了试,本以为自己写的连接池没有问题,结果和同学交流,他说我虽然写了连接池,可是在编程时并没有用到,本人比较懒,所以就没有修改,想直接使用tomcat的连接池就好. 首先修改server.xml文件:         <Context path="" docBase="my site" debug="0" reloadable="true"   crossContext="tr

Tomcat+SQL Server2000连接池配置

server|server2000|sql 终于解决了困扰多天的连接池的问题,写下这编文章与大家一起分享.我是在tomcat5.5.9下配置的,tomcat5.5.X和以前的版本有一些差别,所以配置上也有差别.我就说一下在tomcat5.5.9配置的基本步骤:(确定你以安装好tomcat5.5.9.sql2000) 1.把数据库JDBC驱动拷贝到%TOMCAT_HOME%/common/lib和%TOMCAT_HOME%/webapps/yourweb/WEB-INF/lib下(我的web文件夹