求救!!!数据库连接池出错
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求救!!!数据库连接池出错相关的知识,希望对你有一定的参考价值。
Tomcat提示信息:Cannot get a connection, pool error Timeout waiting for idle object.开始登录没问题,刷新十次Tomcat就出现这个错误,我在每次查询完都在Finally内调用了连接的Close()方法.Tomcat的设置是<Context crossContext="true" debug="5" docBase="afeng" path="/afeng" reloadable="true">
<Resource name="jdbc/zs" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="30000"
username="root" password="" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/zs?autoReconnect=true"/>
有好的解决方法的话再加20,分少,见谅
谢了,把 maxWait值改小问题至少刷新页面正常运行了,但那个错误还是一样出来,数据库也连不上了.maxActive="-1" maxIdle="30" maxWait="-1"按这样设的话,Tomcat启动的时候出错:NumberFormatException: For input string: "-1s" 数据库连接不上.
有没有其它解决方案了?
的确是代码有问题,已经解决了,连接是否为空的语句没有起作用,不过我每次连接完了都使用了Close()方法,新的连接用完了,不知为什么连接池的连接不会被使用
只是出现错误提示吗?是否可以对数据库进行操作?
(我在每次查询完都在Finally内调用了连接的Close()方法)。能否给我看看你的代码。
Cannot get a connection, pool error Timeout waiting for idle object.这种错误,说明池中连接用尽,而用户获取连接等待超时。你只给这么一段连接池的配置是不行的。配置应该没有问题,是你的代码有问题。 参考技术A maxActive="100" maxIdle="30" maxWait="30000
把数值改小一点 30 10 10000
happybase 的连接池
前段时间有个项目使用 hbase 存储一些数据,使用 happybase 类库和 thrift server 交互。使用 happybase 连接池过程中遇到一些问题,就去看了下 happybase 连接池代码,找到了出错原因。
我们先来看下 happybase 的连接池是怎么使用的?
先看下 init 方法,最开始里面声明了几个变量,_lock 保存了一个线程锁,_queue 保存了一个线程安全的先入后出队列,大小是初始化的池子大小,用来存储 hbase 连接,_thread_connection 则保存了一个线程本地变量,具体用途下面会介绍。再就是初始化了 size 大小的连接,并且全部放到 _queue 中。init 最后手动调用了下 connection 方法拿一个连接,目的是什么呢?保证当根据 host 和 port 连接错误的时候,初始化连接池过程中会直接抛错,而不是等到实际用到一个连接的时候再抛错。
下面我们看下 connection 方法:
我们可以看到 connection 方法使用 contextlib.contextmanage 装饰器修饰了,限制了使用时候必须使用 with 关键词。在看连接具体获得代码前,我们先看下连接的 yield 和释放相关的代码。
可以看到拿到一个连接后,会 yield 出去,finally 里会把连接归还连接池,中间的 except 异常需要注意下,当某个连接在执行的时候出现问题时,会捕获异常,并 refresh 一个新的连接,保证最后 finally 归还给连接池的连接是可用的连接。except 捕获的异常必然是 with 代码内的,代码外的异常是无法捕获的,所以需要保证 with 代码块结束了,对连接的使用就结束了,不然就会出现多个线程占用同一个连接这种情况。类似 scan 操作,返回结果是生成器,最好转成 list 在 with 内部返回,不然直接返回生成器的话,with 代码外部遍历时候,其实还是在用这个连接,而其实 with 已结束,连接池就会认为连接已经用完了,会回收掉分配给其他的线程。
我们看个不正确的使用姿势:
这个使用姿势就不对,因为 scan 返回结果是一个generator,with 一结束,连接池认为你这个连接用完了,就会回收这个连接到池子里,再分配给其他线程。而你外部使用地方可能遍历生成器内容,还是会用到这个连接,就会出现多个线程使用一个连接的情况。正确做法是 with 内部将 generator 结果转成 list,保证 with 结束连接使用也结束。
下面看下连接的获得:
会首先获取 _thread_connections 线程本地变量的 current 属性,每个线程的 current 属性都是独立的。注意不同线程的 _thread_connections 都会指向同一个对象,因为这个变量在连接池初始化的时候就确定了。但是 python 的 thread_local 重写了 getattr 方法,里面会调用一个 patch 方法,保证每个线程 local 变量的设置和读取都是独立的。
下面就好理解了,如果连接为空,就去队列取一下,然后 set 到本地变量中。
对于 gevent patch 的服务器, thread local 变量会被 patch 成 gevent 的 local,保证每个协程的 local 都是独立的,所以可以和多线程一样正常使用。
为什么最后会需要加锁来设置线程本地变量,感兴趣的可以网上找下 Python issue1868 相关资料,具体原因会在下篇文章详细介绍。
以上是关于求救!!!数据库连接池出错的主要内容,如果未能解决你的问题,请参考以下文章
求救:ADO可以连上SYBASE数据库吗?如可以选那个驱动程序?
Java EE RAR5038:使用安全套接字层为连接池创建资源时出错