• c3p0--常见异常


    1. 获取资源timeout:
      异常信息如下:
      Caused by: java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.
      [Cause: com.mchange.v2.resourcepool.TimeoutException:
      A client timed out while waiting to acquire a resource from com.mchange.v2.resourcepool.BasicResourcePool@4d5a39b7 -- timeout at awaitAvailable()

      查找发现,获取connection资源timeout的地方,在basicResourcePool类的awaitAvailable方法里,代码很简单:
       1 private void awaitAvailable(long timeout) throws InterruptedException, TimeoutException, ResourcePoolException
       2     {
       3         assert Thread.holdsLock( this );
       4 
       5         if (force_kill_acquires)
       6             throw new ResourcePoolException("A ResourcePool cannot acquire a new resource -- the factory or source appears to be down.");
       7 
       8         Thread t = Thread.currentThread();
       9         try
      10         {
      11             acquireWaiters.add( t );
      12 
      13             int avail;
      14             long start = ( timeout > 0 ? System.currentTimeMillis() : -1);
      15             if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX)
      16             {
      17                 if ( logger.isLoggable( MLevel.FINE ) )
      18                     logger.fine("awaitAvailable(): " + 
      19                                     (exampleResource != null ? 
      20                                                     exampleResource : 
      21                                     "[unknown]") );
      22                 trace();
      23             }
      24             while ((avail = unused.size()) == 0) 
      25             {
      26                 // the if case below can only occur when 1) a user attempts a
      27                 // checkout which would provoke an acquire; 2) this
      28                 // increments the pending acquires, so we go to the
      29                 // wait below without provoking postAcquireMore(); 3)
      30                 // the resources are acquired; 4) external management
      31                 // of the pool (via for instance unpoolResource() 
      32                 // depletes the newly acquired resources before we
      33                 // regain this' monitor; 5) we fall into wait() with
      34                 // no acquires being scheduled, and perhaps a managed.size()
      35                 // of zero, leading to deadlock. This could only occur in
      36                 // fairly pathological situations where the pool is being
      37                 // externally forced to a very low (even zero) size, but 
      38                 // since I've seen it, I've fixed it.
      39                 if (pending_acquires == 0 && managed.size() < max)
      40                     _recheckResizePool();
      41 
      42                 this.wait(timeout);
      43                 if (timeout > 0 && System.currentTimeMillis() - start > timeout)
      44                     throw new TimeoutException("A client timed out while waiting to acquire a resource from " + this + " -- timeout at awaitAvailable()");
      45                 if (force_kill_acquires)
      46                     throw new CannotAcquireResourceException("A ResourcePool could not acquire a resource from its primary factory or source.");
      47                 ensureNotBroken();
      48             }
      49         }
      50         finally
      51         {
      52             acquireWaiters.remove( t );
      53             if (acquireWaiters.size() == 0)
      54                 this.notifyAll();
      55         }
      56     }

      抛出异常的是第44行,而抛出异常的先决条件就是timeout了。表象来看是这样,再继续跟进代码的时候发现,进入等待资源的先决条件是:

      1、available==0(unused==0)
      2、managed。size>=max(池数量已达到最大)
      3、获取到的资源异常:如果设置了checkedoutTest这一项时,进行test的时候失败,导致异常;
      

      所以更直接的原因是以下几种:

      1、请求资源的队列太长,排队时间太长导致超时:线程数量应付不过来大量的请求数量,导致超时
      2、testConnection的原因导致的异常:网络震荡
      3、数据库服务器端无更多的链接可用
      

      那么相应的解决方案:

      1、请求资源过长的,加大maxsize,如果请求量过大的,尽量将min和max设置成一个值,因此不存在shrink和expand的操作,这也是一种性能消耗
      2、testConnection设置在checkin即可,checkout时无需test,否则卡在网络震荡就不好了
      3、检查数据库端的最大链接数。
      4、将c3p0的debug日志打开,检查它的managed、unused、available的分别size
      
    2. deadlock  
  • 相关阅读:
    mysql 主从服务器配置
    Linux命令
    Kali
    Python进阶
    性能测试工具
    sphinx搜索
    页面静态化
    PHP API接口
    线程的生命周期
    多线程的创建
  • 原文地址:https://www.cnblogs.com/leeying/p/3777294.html
Copyright © 2020-2023  润新知