Dev Zone
偏执狂才能生存,人生/事业的路上需要再坚持一下
但是又怎么说得清坚持的结果,道得尽坚持的含义

我使用的是GEF0.10(http://gef.tigris.org),在某一个Fig上点击鼠标右键弹出PopupMenu时,发现有闪烁的现象,经过追查发现,一个鼠标右击动作会分别触发Editor.mousePressed(e)、mouseReleased(e)、mouseClicked(e)三个事件,这些事件最终都要流经ModeManager,而ModeManager采取的是广播的方式分发这些事件,把这些事件依次转发给mode对列中的所有Mode。ModePopup是默认的一个Mode之一,负责提供Fig的弹出菜单功能。而ModePopup中的这三个事件都作了如下的判断: 

   public void mouseClicked(MouseEvent me) {
        boolean popUpDisplayed 
= false;
        
if(me.isPopupTrigger() || me.getModifiers() == InputEvent.BUTTON3_MASK) {
            popUpDisplayed 
= showPopup(me);
            
if (LOG.isDebugEnabled()) {
                
if (popUpDisplayed) LOG.debug("MousePressed detected as a popup and popup displayed and event consumed");
                
else  LOG.debug("MousePressed detected as a popup but no popup to display");
            }
            
return;
     }
        LOG.debug(
"MousePressed is not a popup trigger");
    }

 

其中加红的这段不知道为什么要作me.getModifiers() == InputEvent.BUTTON3_MASK的判断,加上这个判断后只要是鼠标右击动作,ModePopup的mousePressed、mouseReleased和mouseClicked事件中showPopup的代码都要被执行,这样在一个鼠标右击动作中实际上弹出了三次PopupMenu,因此造成了闪烁。解决办法是extend默认的ModePopup,覆盖这三个方法,将判断改成if ( me.isPopupTrigger())即可。

posted @ 2005-05-17 22:10 dev 阅读(539) | 评论 (0)编辑 收藏
 

今天做了一个测试,发现Hibernate的dynamic-update只在两种条件下生效:

1。同一session内,对已经persisit的对象进行update,这里的“已经persist”是指update之前先进行了create或者load调用。代码示例:

Session session = openSession();
User user 
= (User)session.load(User.class,new Long(12));
user.setAddress(
null);
session.update(user);
session.flush();

将hibernate配置成show_sql=true,可以看到update产生的sql语句。

2。不同session之间,update传入的对象是另一个session中的persist对象(对该对象调用了create或者load方法)。代码示例:

Session session1 = openSession();
User user 
= (User)session1.load(User.class,new Long(12));

Session session2 
= openSession();
user.setAddress(
null);
session2.merge(user);
session2.flush();


如果将session2.merge(..)改成update,则会更新所有可更新的属性。

posted @ 2005-05-17 22:10 dev 阅读(2070) | 评论 (0)编辑 收藏
 

今天在csdn上看到了一篇介绍PDCA理论在项目管理中应用的blog,很是感慨,想想才到公司的时候老总也给我们做过相关培训,一年下来,要是没有看到这篇blog,铁定是想不起来了。PDCA(计划、实施、检察、优化)是一个很好的理论,现摘录这篇blog的内容如下,以为珍藏。

以下内容出自:http://blog.csdn.net/wwwxuhong/archive/2004/12/20/222804.aspx 

项目管理是个很大的课题
所有的事物都有其规律

项目管理的规律是什么?
前几天看到一个理论让我眼睛一亮,陈述如下,希望对大家有点启发

PDCA循环是由美国统计学家戴明博士提出来的,它反映了质量管理活动的规律。P(Plan)表示计划;D(Do)表示执行;C(Check)表示检查;A(Action)表示处理。PDCA循环是提高产品质量,改善企业经营管理的重要方法,是质量保证体系运转的基本方式。

项目管理的PDCA环。
PDCA是指以下四个阶段,这四个阶段是环环相扣的,这个周期是周而复始的
P  Plan  计划
D  Do    实施
C Check 检查
A Action 总结、再优化

不管是多大的项目,还是多小的任务,如果都用PDCA环实施,环环相扣,就可以大大提高管理的质量,最大程度地保障项目的成功实施。

PDCA分以下八上步骤
计划阶段
    1、分析现状
    2、找出问题的原因
    3、分析产生问题的原因
    4、找出其中的主要原因
    5、拟订措施计划
实施阶段
    6、执行技术组织措施计划
检查阶段
    7、把执行结果与预定目标对比
总结、再优化阶段
    8、巩固成绩,进行标准化

转贴一篇相关文章
  在企业中,通过众多小小的变革可能实现对整个企业的持久改善,从而获得巨大的成效。这在日语中叫做“改善”(kaizen),每一步都很小,这儿一个小变化,那儿一个小改进,但几年后就能发展出完全不同的产品、工序或服务。
  PDCA循环是由美国统计学家戴明博士提出来的,它反映了质量管理活动的规律。P(Plan)表示计划;D(Do)表示执行;C(Check)表示检查;A(Action)表示处理。PDCA循环是提高产品质量,改善企业经营管理的重要方法,是质量保证体系运转的基本方式。

  PDCA循环的特点PDCA表明了质量管理活动的四个阶段,每个阶段又分为若干步骤。

  在计划阶段,要通过市场调查、用户访问等,摸清用户对产品质量的要求,确定质量政策、质量目标和质量计划等。它包括现状调查、原因分析、确定要因和制定计划四个步骤。

  在执行阶段,要实施上一阶段所规定的内容,如根据质量标准进行产品设计、试制、试验,其中包括计划执行前的人员培训。它只有一个步骤:执行计划。

  在检查阶段,主要是在计划执行过程之中或执行之后,检查执行情况,看是否符合计划的预期结果。该阶段也只有一个步骤:效果检查。

  在处理阶段,主要是根据检查结果,采取相应的措施。巩固成绩,把成功的经验尽可能纳入标准,进行标准化,遗留问题则转入下一个PDCA循环去解决。它包括两个步骤:巩固措施和下一步的打算。

  PDCA循环四阶段各步骤。

  1.PDCA循环一定要按顺序进行,它靠组织的力量来推动,像车轮一样向前滚进,周而复始,不断循环。

  2.企业每个科室、车间、工段、班组,直至个人的工作,均有一个PDCA循环,这样一层一层地解决问题,而且大环套小环,一环扣一环,小环保大环,推动大循环。

  这里,大环与小环的关系,主要是通过质量计划指标连接起来,上一级的管理循环是下一级管理循环的根据,下一级的管理循环又是上一级管理循环的组成部分和具体保证。通过各个小循环的不断转动,推动上一级循环,以至整个企业循环不停转动。通过各方面的循环,把企业各项工作有机地组织起来,纳入企业质量保证体系,实现总的预定质量目标。因此,PDCA循环的转动,不是哪一个人的力量,而是组织的力量、集体的力量,是整个企业全体职工推动的结果。

  3.每通过一次PDCA循环,都要进行总结,提出新目标,再进行第二次PDCA循环,使质量管理的车轮滚滚向前。PDCA每循环一次,质量水平和管理水平均提高一步。

  PDCA循环不仅是质量管理活动规律的科学总结,是开展质量管理活动的科学程序,也是一种科学管理的工作方法。它同样可以在质量管理活动以外发挥重要效用。

  PDCA管理法在营销中的运用在运用PDCA循环进行市场营销管理方面,已经有一些优秀企业走在了前头。

  海尔集团纯熟地采用PDCA管理法来实施销售任务的计划、组织和控制。每年年终,集团商流、各产品本部根据本年度的销售额完成情况,结合各产品的发展趋势及竞争对手分析等信息,制定下一年度的销售计划,然后将这一计划分解至全国11个销售事业部。销售事业部长根据各工贸上年的完成情况、市场状况分析等信息再将销售额计划分解至其下属各工贸公司。工贸公司总经理将任务分解至各区域经理,由他们将任务下达至区域代表,区域代表将自己的销售额任务分解至其所管辖的营销网络。同时,海尔还从时间纬度上进行分解:年度计划分解至月度,月度计划分解至每日。这样,处于管理层的每位管理者都可以对下属每日的工作状况进行监督,并及时实施纠偏,最终控制每一个具体网点。海尔集团在新产品开发、新品上市等所有方面都遵循PDCA管理方法。这种做法可以保证“人人都管事,事事有人管”,避免出现管理的真空。

  PDCA管理法运用于每日的事务管理,就形成了独具海尔特色的OEC日清体系。每人均处于相应的岗位上,每一岗位均有不同的职责,并分配相应的指标,员工的激励直接与指标挂钩。指标又可分为主项指标与辅项指标以及临时任务指标等。每人在当日晚上分析一天的各项任务完成情况,并找出差距原因及纠偏办法,以使今后的工作质量得到提高,由此构成了持续不断的改进过程。员工在做完当日总结后,对明日工作做出计划,然后将OEC日清表交至主管领导处,由主管领导进行审核控制并对下属的当日工作进行评价和激励。

  OEC管理法的主要理念,海尔认为是“坚持两个原则,最大限度地对待两种人”,即坚持闭环原则,坚持优化原则,最大限度地关心员工的生活,最大限度地满足用户的需求。所谓闭环原则,指凡事要善始善终,都必须遵循PDCA循环,而且是螺旋上升。所谓优化原则,指根据木桶理论,找出薄弱项,及时整改,提高全系统的水平。在一个企业的运营过程中,必然存在着许多环节,只要找出制约企业经济效益提高的某一关键环节,把首要矛盾解决了,其他矛盾就可以迎刃而解。

  张瑞敏说,海尔生产线每天要出大大小小几万台家电产品,我们不能考虑出了问题如何处理,而要追求不出任何问题。OEC管理法把质量互变规律作为基本思想,坚持日事日清,积沙成塔,使员工素养、企业素质与管理水平的提高寓于每日工作之中,通过日积月累的管理进步,使生产力诸要素的组合与运行达到合理优化的状态,不增加投入就可使现实生产力获得尽可能大的提高,从而令管理收到事半功倍的效果。

  海尔把PDCA运用到企业内部的营销队伍管理上,那么,这种管理方法对外部营销是否适用呢?

  上海通用汽车公司成功地把此方法应用于自己的经销体系中,极大地改善了经销商的服务。在其近100家经销商中,上海通用奉行的政策是,对一些业务表现不好、不能完成上海通用的要求、不能在市场上进行有效的开拓,或者在售后服务方面不能够完全按照上海通用的理念和规范去操作的经销商,会先给他们做一个PDCA改进计划。完成了这个计划性的四部曲后,经销商的整个市场营销的管理工作应该会随之步入一个良性循环的轨道。如果还是不行,经销商就会被淘汰掉。

  由上可知,PDCA管理法的核心在于通过持续不断的改进,使企业的各项事务在有效控制的状态下向预定目标发展。

posted @ 2005-05-17 22:09 dev 阅读(1704) | 评论 (0)编辑 收藏
 

  先前的项目采用的是TyrexFactory作为事务工厂的实现,但是运行的过程中发现很不稳定,处理大对象时容易出现事务超时的错误,即使事务设置的超时时间很长也是这样,将jotm及其相关jar copy 到lib中之后,换成JotmFactory,发现TransactionFactory.getTransactionFactory竟然报NoSuchElementException。后来发现是carol.jar中的CarolConfiguration需要装载jndi.properties文件进行初始化,而tyrex.jar自身有一个同名的文件,正是因为CoralConfiguration装载了这个同名的文件才产生了异常,去掉tyrex.jar就可以了。

posted @ 2005-05-17 22:08 dev 阅读(405) | 评论 (0)编辑 收藏
 
Ofbiz2.1有两个bug,都涉及到线程安全性,小并发的时候不容易发现,大并发下有时候会出现,并发数越高出现的频度就比较高,尤其对于实体引擎的那个bug,在系统初始化的时候如果遭遇大并发,会有一定频度的出现。
 
1。entity engine的ModelEntity.getField方法存在线程安全隐患,会造成 XXXX is not a field of XXX的异常,以下是原有代码片断:

    
public ModelField getField(String fieldName) {
        
if (fieldName == nullreturn null;
        if (fieldsMap == null) {
            fieldsMap = new HashMap(fields.size());
            for (int i = 0; i < fields.size(); i++) {
                ModelField field = (ModelField) fields.get(i);
                fieldsMap.put(field.name, field);
        }
        return (ModelField) fieldsMap.get(fieldName);
    }

由于getField方法没有同步(会造成性能下降),因此红色标标注的那段代码存在线程安全问题,必须进行同步。在大并发下如果多个调用这个方法,最先调用的线程没有执行完循环的情况下,后续的线程通过最后的语句return的时候得到的就是Null(fieldsMap已经被第一个线程赋值了,后续线程不会进入红色标准的代码区域)。
修改后的代码如下:
   public ModelField getField(String fieldName) {
        
if (fieldName == nullreturn null;
        
if (fieldsMap == null) {
             createFields();
        }
        
return (ModelField) fieldsMap.get(fieldName);
    }

    
public synchronized void createFields()
    {
             fieldsMap 
= new HashMap(fields.size());
 
             
for (int i = 0; i < fields.size(); i++) {
                 ModelField field 
= (ModelField) fields.get(i);
 
                 fieldsMap.put(field.name, field);
             }
    }
 
这个Bug在3.0中已经被修正。
 
2。UtilCache.get方法同样存在线程安全隐患,会造成LinkedList.remove或者LinedList.addFirst的空值针异常,不注意还会以为是LinkedList的bug。以下是原代码片断:
    public Object get(Object key) {
        
if (key == null) {
            missCount
++;
            
return null;
        }
        UtilCache.CacheLine line 
= (UtilCache.CacheLine) cacheLineTable.get(key);
        
if (hasExpired(line)) {
            
// note that print.info in debug.properties cannot be checked through UtilProperties here, it would cause infinite recursion
            
// if (Debug.infoOn()) Debug.logInfo("Element has expired with key " + key);
            remove(key);
            line 
= null;
        }
        
if (line == null) {
            
// if (Debug.infoOn()) Debug.logInfo("Element not found with key " + key);
            missCount++;
            
return null;
        }
        
// if (Debug.infoOn()) Debug.logInfo("Element found with key " + key);
        hitCount++;
        if (maxSize > 0) {
            keyLRUList.remove(key);
            keyLRUList.addFirst(key);
        }

        return line.getValue();
    }
红色标准的部分是有问题的代码,修改后的代码如下:
    public Object get(Object key) {
        
if (key == null) {
            missCount
++;
            
return null;
        }
        UtilCache.CacheLine line 
= (UtilCache.CacheLine) cacheLineTable.get(key);
        
if (hasExpired(line)) {
            
// note that print.info in debug.properties cannot be checked through UtilProperties here, it would cause infinite recursion
            
// if (Debug.infoOn()) Debug.logInfo("Element has expired with key " + key);
            remove(key);
            line 
= null;
        }
        
if (line == null) {
            
// if (Debug.infoOn()) Debug.logInfo("Element not found with key " + key);
            missCount++;
            
return null;
        }
        
// if (Debug.infoOn()) Debug.logInfo("Element found with key " + key);
        hitCount++;
        
if (maxSize > 0) {
            synchronized ( 
this)
            {
                 keyLRUList.remove(key);
                 keyLRUList.addFirst(key);
            }
        }
        
return line.getValue();
    }

这个BUG在3.0种也修正了。
posted @ 2005-05-17 22:07 dev 阅读(250) | 评论 (0)编辑 收藏
 
1。XAPool是如何wrap jdbc driver返回的PreparedStatement的。
以下是StandardConnectionHandler中的checkPreparedCache代码片断
    synchronized PreparedStatement checkPreparedCache(
        String sql,
        
int type,
        
int concurrency)
        throws SQLException {
        log.debug(
            
"StandardConnectionHandle:checkPreparedCache sql='" + sql + "'");
        PreparedStatement ret 
= null// the return value
        
// NOTE - We include the Connection in the lookup key. This has no
        
// effect here but is needed by StandardXAConnection where the the physical
        
// Connection used can vary over time depending on the global transaction.
        String lookupKey = sql + type + concurrency;
        
// used to lookup statements
        if (preparedStatementCache != null) {
            Object obj 
= preparedStatementCache.get(lookupKey);
            
// see if there's a PreparedStatement already
            if (obj != null) { // if there is
                ret = (PreparedStatement) obj; // use as return value
                try {
                    ret.clearParameters(); 
// make it look like new
                } catch (SQLException e) {
                    
// Bad statement, so we have to create a new one
                    ret = createPreparedStatement(sql, type, concurrency);
                }

                preparedStatementCache.remove(lookupKey);
                
// make sure it cannot be re-used
                inUse.put(lookupKey, ret);
                
// make sure it gets reused by later delegates
            } else { // no PreparedStatement ready
                ret = createPreparedStatement(sql, type, concurrency);
                inUse.put(lookupKey, ret);
                
// will get saved in prepared statement cache
            }
        } 
else {
            ret 
= createPreparedStatement(sql, type, concurrency);
        }
        
// We don't actually give the application a real PreparedStatement. Instead
        
// they get a StandardPreparedStatement that delegates everything except
        
// PreparedStatement.close();

        ret 
= new StandardPreparedStatement(this, ret, lookupKey);
        
return ret;
    }

2。StandardPreparedStatement的Close方法代码片断
    public void close() throws SQLException {
        
// Note no check for already closed - some servers make mistakes
        closed = true;
        
if (con.preparedStmtCacheSize == 0) {
            
// no cache, so we just close
            if (ps != null) {
                ps.close();
            }
        } 
else {
            con.returnToCache(key);
            
// return the underlying statement to the cache
        }
    }

3。xapool StandardPoolDataSource的getConnection 原理:
     StandardPoolDataSource.getConnection --> GenericPool.checkOut-->StandardPoolDataSource.create -->StandardPoolDataSource.getPooledConnection:返回StandardPooledConnection。
 
     StandardPooledConnection通过StandardDataSource.getConnection获取jdbc driver返回的connection(physical connection),然后通过工厂方法newConnectionHandle采用StandardConnectionHandler对该connection进行包装。StandardConnectionHandler对PreparedStatement进行重新包装和Cache,对connection.close进行了控制。
 
4。xapool StandardXAPoolDataSource的getConnection的原理:
   StandardXAPoolDataSource.getConnection -->StandardPoolDataSource.getConnection-->StandardXAPoolDataSource.create -->XADataSource.getXAConnection -->StandardXADatasource.getXAConnection:返回StandardXAConnection。
    StandardXAConnection通过StandardDataSource.getConnection获取jdbc driver返回的connection(physical connection),然后通过工厂方法newConnectionHandle采用StandardXAConnectionHandle对该connection进行包装。StandardXAConnectionHandler继承自StandardConnectionHandler。
 
5。xapool从StandardPoolDataSource获取的 Connection的关闭原理。
   StandardPooledConnection.close-->StandardConnectionHandler.close(设置closed=true,回收PreparedStatement)-->StandardPooledConnection.closeEvent-->StandardPoolDataSource.connectionClosed-->GenericPool.checkIn(返回连接池)
 
6.xapool中对连接池进行管理的类是GenericPool,该类的checkOut和checkIn方法分别完成连接获取和连接回收功能。checkOut从unlocked池中获取可用的连接,如果需要进行检查或者测试,然后返回;如果发现unlocked池中没有连接,在连接数小于maxSize的时候调用PoolHelper的实现类创建连接,如果连接数已经达到或者超过maxSize,调用wait使当前进程进入等待状态(等待期限和等待间隔可以设置),如果等待过程中其他线程释放了connection返回可用的connection,否则异常:GenericPool:checkOut ERROR  impossible to obtain a new object from the pool
posted @ 2005-05-17 22:07 dev 阅读(1600) | 评论 (0)编辑 收藏
 
  1. sleepTime:PoolKeeper检测时间间隔
  2. lifeTime:连接生命周期(上次访问时间-当前时间)
  3. deadLockMaxWait(:超过最大连接之后的调用getConnection的等待时间
  4. deadLockRetryWait:超过最大连接之后的调用getConnection等待,在等待中重试的时间间隔
  5. maxSize:连接池的容量

deald-lock-max-wait和dead-lock-retry-wait的设置要小心,这两个参数的意义见我的另一个日志:XAPool原理简要分析。dead-lock-retry-wait最好设置得比较短,这样不至于线程等待很长时间,dead-lock-max-wait的设置不要太长,一般是设置成比最高并发数下应用处理时间稍长一点,设置过短在大并发下会造成提交实效导致应用数据的丢失,因为超过xapool在超过等待dead-lock-max-wait之后会异常:没有可用连接分配。

 

sleepTime是对Connection idle检测线程PoolKeeper的检测时间间隔设置。PoolKeeper会定时监测是否存在超过lifeTime的connection然后释放掉这些connection。不过PoolKeeper在运行的时候会检查running属性,以下是它的run方法中的代码片断:

  while (! running && !Thread.interrupted()) {
      System.err.println(
"!!!!"+System.currentTimeMillis());
   
try {
    synchronized (
this) {
     wait(
this.sleepTime); // wait for timeout ms before attack
    }
   } 
catch (InterruptedException e) {
                                
break;
   }
   
this.pool.cleanUp(); // clean up the Pool and reallocate objects
  }
  
// release the pool.
  this.pool = null;

之所以把这段代码粘出来,是因为running属性默认是true,而GenericPool在启动PookKeeper的时候并没有改变这个值,因此PookKeeper永远不会运行起来。也许这是xapool的另一个bug:)

连接池的容量设置是有讲究的,一般至少等于AppServer(或者叫WEB 容器)的最大并发数。因为xapool在达到maxSize的时候,如果还有线程需要连接,会进入等待状态(通过deadLockMaxWait设置最大等待时间,deadLockRetryWait设置等待间隔),在大并发下会造成App Server容器线程池满,Server在一段时间内(deadLockMaxWait)停止响应的现象。将连接池的容量设置成大于App Server的最大并发数,可以尽可能的避免这种情况。App Server的最大并发数=App Server的线程池线程数,Tomcat默认是75,Websphere默认是50。集群环境下,集群的最大并发数=每台集群服务器的最大并发数之和

posted @ 2005-05-17 22:06 dev 阅读(2285) | 评论 (1)编辑 收藏
 
现状:我们的项目中使用了ofbiz2.1,并采用JotmFactory作为TransactionFactory,使用Oracle9i数据库,在大并发测试的时候发现数据库游标暴涨并且不释放,最终导致游标溢出。
 
原因分析:ofbiz  entityengine的很多操作都是使用PreparedStatement完成的,这无可厚非,问题是JotmFactory采用的是XAPool作为连接池,而XAPool对PreparedStatement进行了Cache,同时Oracle有一个出名的内存漏洞,PreparedStatement使用之后必须关闭,如果不关闭连续进行SQL查询会造成前面SQL的游标不能释放;此外JotmConnectionFactory没有允许对XAPool做更多的配置,按照它使用XAPool的方式,XAPool会对PreparedStatement进行Cache。Oracle漏洞+ofbiz的不周全的使用方式+xapool的机制造成了游标不释放最终溢出的异常。
 
 
解决办法:修改JotmConnectionFactory,调用StandardXAPoolDataSource的setPreparedStmtCacheSize(int)的方法,将preparedStmtCacheSize设置为0。需要注意的是xapool在目前的版本(1.4)当preparedStmtCacheSize=0的时候存在一个bug,close PreparedStatement的时候会报NullPointerException,请参考我的另一个日志XAPool1.4的bug
 
posted @ 2005-05-17 22:06 dev 阅读(517) | 评论 (0)编辑 收藏
 
现状:XAPool1.4有一个bug,当设置preparedStmtCacheSize=0的时候,关闭连接会抛出NullPointerException
 
原因:StandardConnectionHandle在Close的时候调用了preparedStatementCache.cleanupAll(),没有进行判断;而当preparedStmtCacheSize设置为0的时候,StandardConnectionHandle在setupPreparedStatementCache中把preparedStatementCache设置为null,以下setupPreparedStatementCache是方法中的源代码片断:
 
 protected void setupPreparedStatementCache() {
  log.debug(
"StandardConnectionHandle:setupPreparedStatementCache start");
  
if (preparedStmtCacheSize == 0) {
   log.debug(
    
"StandardConnectionHandle:setupPreparedStatementCache return with 0");
   preparedStatementCache 
= null;
   
return;
  }
 
解决办法:修改setupPreparedStatementCache,如下:
  if (preparedStmtCacheSize == 0) {
   log.debug(
    
"StandardConnectionHandle:setupPreparedStatementCache return with 0");
//   preparedStatementCache = null;
   preparedStatementCache = new PreparedStatementCache(0);
   
return;
  }
posted @ 2005-05-17 22:05 dev 阅读(212) | 评论 (0)编辑 收藏
 
现状:在我们的项目中使用了Ofbiz2.1,TransactionFactory配置为JotmFactory,数据库是Oracle9i,lifeTime设置为120000(2分钟)在大并发测试的时候发现经常Closed Connection的异常。
 
原因:Oracle数据库会检查physical connection的idle时间和使用次数并关闭长时间idle的physical connection,如果应用对从连接池中
获取的connection不进行检查,或者连接池仔返回可用连接之前不进行检查,在使用过程中就会Closed Connection的异常。大多数数据库都会检查physical connection的idle时间。
 
解决办法:调用StandardPoolDataSource或者StandardXAPoolDataSource的setCheckLevelObject(int)方法设置连接检查级别,参数取值如下:
  1. 0:不检查
  2. 1:对unlocked池中获取的连接进行Closed检查
  3. 2:对unlocked池中获取的连接进行sql测试,需要设置setJdbcTestStmt(Test SQL)
  4. 3:对所有unlocked池中的连接进行Closed检查
  5. 4:对所有unloked池中的连接进行测试,需要设置setJdbcTestStmt(Test SQL)
 
 
posted @ 2005-05-17 22:04 dev 阅读(1057) | 评论 (0)编辑 收藏
仅列出标题
共3页: 上一页 1 2 3 下一页