磁盘I/O也能够让程序不正确

阅读更多
       HSQLDB数据库执行SHUTDOWN命令,如果系统磁盘I/O性能不是很好的话,也能够造成程序的错误。
      
       该BUG是因为HSQLDB 数据库执行ShutDown命令之后,由于客户端正在运行BT, Emule这样的程序,使得客户端的磁盘一直都处于I/O状态。因此,在程序调用shutdown命令之后,文件系统并没有在非常短的时间内完成文件操作。

       因此,在程序执行到后面,需要对已经生成的文件进行访问的时候,出现了错误。而出现的错误也是比较怪异。一会儿出现文件不存在;一会儿又出现有其他的进程正在对文件进行访问;一会儿还出现客户端无法加载CLASSES;有些时候又可以正常了。

       通过分析,我断定是因为程序在调用shutdown的时候,文件系统执行shutdown较慢的缘故。
        出现文件不存在,是说:在程序执行的哪一点,hsqldb还没有执行完shutdown命令,也就是说在文件系统中还根本没有这个文件;
        有其他的进程正在访问,也就是说,程序在执行的哪一点,还有HSQLDB的Connection还连接在数据库上,可见数据库要执行shutdown命令还是相当耗时的;
        另外,客户端无法加载Classes,因为我们的applet需要访问的classes都是通过jar文件传输过去的,出现这个问题,明显是由于系统I/O比较异常,系统无法在要求的时间加载到APPLET所需要的JAR包。
      
       可见,程序确实还不是很Strong。我以前还从来没有遇到这个问题。

        判定到这个问题之后,我肯定这个错误在于客户端的磁盘I/O系统。因此,我调查了一些客户端测试的环境。原来,客户端的机器一直都在使用emule和bt软件,这两个软件对系统磁盘I/O的性能影响还是比较大。将客户端的bt和emule关掉之后,发现程序正常:)

       可见,磁盘的I/O也能够让程序运行不正确,不要以为调用了statment.execute("shutdown"); 文件系统中立马就会有hsqldb的.script文件了:)这个是不成立的。另外,我们在调用statment.execute("shutdown")之后,系统并不会等到文件操作完成,该语句才返回。从这个道理来讲,程序和文件系统不是同步的,而是消息的。程序给文件系统发送命令,文件系统响应,返回。但是,文件真正存储到磁盘中,可不是程序可以预知的。

       为了增强程序的健壮性,只好在程序执行的下一点,先Thread.sleep(1000),然后去判断文件是否存在。如果文件不存在,那么报错。

       但是,有多少机会,文件I/O操作是在1s之内完成的呢?只要客户端系统不使用耗I/O的程序,应该都是没有问题的。如果使用了,那多半还是会有问题。不过,sleep 1s也就算了。

你可能感兴趣的:(HSQLDB,软件测试,thread)