Chinaunix首页 | 论坛 | 博客
  • 博客访问: 591079
  • 博文数量: 718
  • 博客积分: 4000
  • 博客等级: 上校
  • 技术积分: 4960
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-17 13:24
文章分类

全部博文(718)

文章存档

2011年(1)

2008年(717)

我的朋友

分类:

2008-10-17 13:28:07

  以前我一直是用使用数据源的系统测试JDBMonitor,昨天我准备把JDBMonitor嵌入到一个小的jsp留言板中,这个留言板写的非常简单,数据库操作也是connection随取随用、用完了就关这种最简单的形式,这倒是帮助我发现了一个超级大bug.在记事本运行中常常不规律的DataBaseDBListener的logSQL方法报空指针错误,是在logStatement.setString(1, randomGUID.toString());这一句抛出的,我跟踪到mysql驱动的内部(我使用的是mysql数据库做DataBaseDBListener的输出数据库),发现在setString的实现中会去调用connection的方法,而此时connection已经是null了,所以会报空指针错误。
 
  从其不规律的特点我判断出应该是多线程导致的问题。我跟踪发现,有的时候是先调用DataBaseDBListener的close后logSql才被调用。经过分析找出了问题所在,问题就在DBLogger中内部类LogConsumer的startConsumer方法,这个是修改以前的代码:
 
  
 for (;;)
 {
  SQLInfo info = (SQLInfo) channel.take();    

  if(info==null)
  {
   ontinue;
  }
  for (int i = 0, n = dbListeners.length; i < n; i++)
  {
   dbListeners[i].logSql(info);
  }

 }

 
  在调用channel.take()以后,这个SQLInfo就从channel中去除了。这时如果DBLogger的方法被调用,那么即使dbListeners[i].logSql(info)仍然在运行,但是DBLogger会认为channel已经空了,所有的dbListeners都可以被close了,而在DataBaseDBListener的close方法中会把输出目标数据库connection关掉,那么此时如果DataBaseDBListener的logSql方法还在调用的话,那么一旦使用这个connection,那么就会出现错误了。
 
  我是如下修改的:修改BlockedChannel类,去掉其take方法,增加一个peek方法和一个remove方法,peek方法是从channel中查出一个对象,但是不把它从channel中移走,只有调用remove方法后才会被移走。
 
  修改DBLogger中内部类LogConsumer的startConsumer方法为如下:
 
  
 for (;;)
 {
  SQLInfo info = (SQLInfo) channel.peek();
  if(info==null)
  {
   continue;
  }
  for (int i = 0, n = dbListeners.length; i < n; i++)
  {
   dbListeners[i].logSql(info);
  }
  channel.remove(info);
 }

 
  在调用channel.take()以后,这个SQLInfo就从channel中去除了。这时如果DBLogger的方法被调用,那么即使dbListeners[i].logSql(info)仍然在运行,但是DBLogger会认为channel已经空了,所有的dbListeners都可以被close了,而在DataBaseDBListener的close方法中会把输出目标数据库connection关掉,那么此时如果DataBaseDBListener的logSql方法还在调用的话,那么一旦使用这个connection,那么就会出现错误了。
 
  我是如下修改的:修改BlockedChannel类,去掉其take方法,增加一个peek方法和一个remove方法,peek方法是从channel中查出一个对象,但是不把它从channel中移走,只有调用remove方法后才会被移走。
 
  修改DBLogger中内部类LogConsumer的startConsumer方法为如下:
 
【责编:Zenghui】

--------------------next---------------------

阅读(246) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~