今天负责把多个系统的db2数据库迁移到另外一台机器上。同时要修改WebSphere的数据源,让它指向新的数据库。以前没做过,对于数据库操作,我向来是要用的时候再去翻资料的。开始考虑使用备份、还原的方式,但版本不一样,原来是7现在是8,操作系统也不一样,原来是AIX,现在是Windows,这样备份还原是行不通的,于是采用db2move。
看看db2move的命令说明,大致就明白怎么做了,于是我就开始实战了。我采用最简单的方式,原机器上使用db2move &dbname export生成文件,在目标机上ftp拿到生成的文件,然后使用db2move &dbname import。目标机上只要创建一个新库,无需使用DDL生成表。信息显示所有表都ok,很快就搞定一个数据库,connect上去查看,表自动生成,数据也完全一致。然后在WebSphere所在机器上重新catalog新的数据库,语法也是现查的,现记录如下:catalog tcpip node &nodename remote &ip server &port, terminate, catalog db &remotedbname as &dbaliesname at node &nodename,terminate。加&表示根据实际设置的值。Db2 connect试试,新的连接正常。进入Administartor Console修改数据源配置,然后保存。重启server,测试完全正常。一个数据库搞定。
下面一个是我帮别人迁移的数据库,我对其表结构,表空间等都不知道。不管三七二十一,我先照着刚才办法做。Export一切正常,import前面的表都正常,快结束发现报错了,报创建表失败。到相应表的msg文件发现错误描述如下:
SQL3319N 创建表时发生 SQL 错误 "-286"。
SQL0286N 找不到页大小至少为 "8192"、许可使用授权标识 "DB2ADMIN"
的缺省表空间。 SQLSTATE=42727
原来需要8k页大小的表空间。这简单,使用控制中心新建一个8k的表空间。然后需要让出错的表使用这个表空间,也就是说要要使用DDL语句先创建这个表了。连上原来的数据库,生成这个表的DDL语句,修改tablespace名,改为新建的表空间,然后到新的数据库上执行。我不想重新再import所有表了,怎么做到呢,先看看生成的那些文件,有个db2move.lst,然后是每个表的ixf和msg文件,lst文件居然可以用文本打开,发现里面一行就是一个表,估计这就是需要导入表的列表了。删除那些已经正常导入的表信息,只留没导入的表,然后重新运行db2move &dbname import,这下一切正常了。然后就是剩下的同样工作了。
值得注意的是,db2move只导入表的信息,其它如view,trigger等均需通过DDL语句或控制中心添加。忙了一天,是为此记。
吃过午饭,随意溜达,信步走到开发区的一片绿地上去。说是绿地,地方倒也不大,一块草坪,其上点缀几棵小树,树的荫盖稀疏,即使人独躺其下也能感受阳光透过的刺目眩光。幸好今天多云,加上已到秋天,阳光已经失去如夏日那般的威力了。草坪并不禁止践踏,这大概因为并非什么名贵的进口草坪的缘故,也不需要太多的维护费用,可以任其夏荣冬枯。这种草并不抱簇成团,而是一根根坚韧的往外生长,因而躺在上面并不舒服,感觉刺的厉害。但我却喜欢这种草,朴素,随处可见,生命力顽强,令我回忆起小时候在河堤上玩耍的情形来。
躺了会,的确有点刺背,就坐起身来。目光所及,前面草地上有只不知名的小鸟,白头黑身,长长的尾巴,正在草中寻虫吃吧,走几步小嘴一啄,尾巴也上下颤动,可爱的很。它漫无目的的走着,大体向我靠近了,我心中一阵高兴,幻想着它能来到身边,我伸出手掌让它停在上面。我屏住呼吸,尽量不弄出一点动作和声音,只是静静的看着它,欣赏它的美丽。可它又慢慢走远了,可能发现了我,头也不回的一摇一摆的往前走去。小鸟终究是怕人的。
于是我便站起身来。草坪旁边是一个人工湖,湖边是一座叠石流水,水绕着叠石,向下流淌到湖中,倒也别具匠心。叠石不高,顶上好像能上去的样子,我生性好动,就想往上爬。难度不大,但也得手脚并用,看准落脚点,手上抓牢,很快就站在最高点了。可以俯瞰湖面,波光粼粼,水上还有一些睡莲,不由浮想起:“鱼戏莲叶东,鱼戏莲叶西,鱼戏莲叶南,鱼戏莲叶北”的诗句来。但好像没有鱼的动静,也许这个湖也刚建不久,还未长成吧。湖岸对面一个老者,拿根小竹竿在忙活着,应该不是钓鱼吧,鱼都没长大呢!带着一丝好奇,我又爬下叠石,转到对岸去看看。
他旁边放了个盛水的小盒子,里面一些非常小的鱼在游着,我以为是鱼苗呢,就上去问:“你是要把这些鱼放进湖里吗?”他没抬头,旁边又来了几个民工样的人,也凑上身来,其中一个问:“鱼这么小,有什么用?”老者这下答话了:“我去喂小乌龟。”“小乌龟不吃小鱼吧”……原来他是用小网兜把可怜的小鱼捞上来,然后装回家喂小乌龟。我很快走开了,好的心情一下荡然无存。这么小的鱼,好不容易才在这片池塘出生,却因为某人家里不知道吃不吃它的小乌龟,被装到盒子里,注定其灭亡的命运。而我只能幻想鱼群在莲叶下游过的景象。我忽然想起为什么我是走开,而不是将鱼放到湖里去。那样会得罪人,是啊,“少管闲事”的观念已经深入骨髓了。但我也只是想想,头也不回的往公司走去。
Cache作为提高性能的有效手段可以说是无处不在的。CPU有一级缓存,二级缓存;数据库有自己的数据缓存;内存实质上就是硬盘的缓存。。。。。。而程序中的缓存也能够有效的减少与存储设备的交互,增加应用的并发能力。
我通过在实际项目中自行设计和使用cache,逐渐提高了系统的并发能力,但同时也感觉到了很多的不足:
1. 因为是在原有系统基础上优化,cache的处理没有统一的规划,而是头痛医头,脚痛医脚。cache分散在系统各个模块,很难想起哪些模块使用了cache
2. cache的实现各种各样,有的是单例、有的是static对象,而cache对象与数据库的交互也是直接硬编码在原有系统中,难于维护
3. cache的参数如刷新间隔。。。。。。未使用配置文件,而是直接定义在cache的类文件中,对配置的更改就需要更新整个类,进而影响系统的运行
4. 缺少对cache的监控机制和log机制,出现问题很难去跟踪和解决。
经过一段时间具体项目的洗礼,对java也有了进一步的认识,我也可以有能力来解决一直困扰心中的cache的这些问题了。想法很简单,就是能够通过单一的配置文件,对系统中的所有cache进行统一的管理,各个cache所在的模块,和cache的配置参数,都能够一目了然。而对配置文件的重载功能也是我要考虑的问题,希望对某些cache的配置的更改能够对其它cache无影响,同时这些更改也能在不影响应用运行状态的情况下进行。当然既然是统一管理,就需要做到接口的统一。我定义了Cache和CachePersistence两个接口,然后不同的cache可以提供不同的实现,实现类需要在配置文件中指定,同时系统提供默认的实现,以满足简单的应用。想了就要开始做,我也没想一开始就做出象OSCache或JbossCache那样通用的cache来,也许经过不断的交流,不断的完善最终可以做到。经过简单的设计,我就开始写代码了,就我一个人,也算是XP编程了,呵呵!cache的配置参数,我根据项目经验想到了几个,可能还可以有,但目前我不知道,需要在更多的项目应用中去发现,具体可以看我的包中的cache.xml文件,有对配置项的具体说明。
从开始开发到最后写完测试类,也就不到一个星期的时间(上班的空余时间和加班写),当中也进行了几次重构。总的来说,还算满意,这也算俺的第一个开源项目啊,呵呵!
具体如何使用,很简单,你有兴趣可以实现Cache接口,我内置了基于HashMap的Cache,应该能满足大部分应用的需要。CachePersistence就是你的对象与存储设备交互的实现了,你一般需要实现这一接口,然后配置在配置文件中。然后通过CacheFactory得到Cache,通过Cache接口使用对象。对Cache的操作你可以当成一个Map来使用,由容器来自动处理何时与存储设备的交互,你只要配置好就ok了。另外可以参考src中的test包,里面是我对Cache的功能测试代码,也能作为使用cache的实例的。
说了这么多,大家如果有兴趣,可下载我的全部文件,里面包括jar、src、lib、javadoc还有配置文件,点击这里http://www.blogjava.net/Files/pesome/pcache.zip。更欢迎大家在实际的项目中使用我的cache,如果有任何问题都可以跟我联系,mailto:pesome@163.com。谢谢!
近来研究AOP,在了解其实现如AspectJ和Spring等之余,也多了些思索.
早晨一觉醒来,顿觉精神气爽,再看时间还早,也就躺床上闭目养神.而思维此时却象脱缰的野马,纵横驰骋,不知不觉就想到我所从事和钟爱的软件上来.忽发奇想:其实软件的最终目标就是模拟真实世界,甚至进一步说就是创造世界(看过Matrix的朋友应该能理解).所以OOP,AOP或今后将出现的什么新的软件思想也都只是这一进程中的小浪花而已,而他们的出现及发展,也就是为了更好的模拟我们的生活.
OOP的出现之所以被称为一个很大的突破,正因为它很大程度上符合世界的构成.java有 “Everything is object”之说,正是有了Object这个有利的武器,使得我们在用OOP表现世界的某些方面时能够得心应手.但我们世界除了Object还有很多其它的东西,比如道德,法律,规范,规律……而AOP的出现正是模拟这些方面.
以我们最熟悉的对象“人”作为考察的对象.人做为对象由多个对象组成,如手,眼……我们作为世界的个体,首先守很多规律的制约.如万有引力定律,牛顿三大定律……这些规律是无处不在的,任何人都无法去避免或改变.还有法律,这是人为拟定的对某些个体具有约束性的规范,如果相应个体违法,则会受到法律的制裁.注意这里是“某些个体”,各国的法律只在本国范围内有效,不同的法律又有不同的受众.这样对个体而言,你就受到某些法律的约束.你知道法律可以决定去遵守或违背它,而你不知道,法律也是客观存在,你不去违背,可能根本感受不到它,而在你即使毫不知情的情况下违背时,它也会显示它的威力.至于如道德或规范等,其强制性不如法律,但就与个体的相互关系而言其实与法律完全一样.
如果从程序的角度来实现上面的相互关系.仅用OOP的思想,就会非常的困难.先说这些定律,他们无时不在,无处不在,只是看什么定律对你当前的行为有影响.如你要上上网,听听歌,可能感受不到万有引力定律和牛顿定律的存在,而你要从12层的楼往下跳试试,万有引力定律和牛顿定律直接决定了你的生死.用程序实现上上网,听听歌或跳跳楼都可做到.你听歌可以计算对耳膜的震动量,音乐对你神经的刺激量;上网可以计算你颈部僵硬时间的长短,计算你网上泡mm的兴奋度;跳楼则根据万有引力定律计算你坠地时的速度和对身体触地部位的冲量.在这些行为中,人是同一个人,也就是同一个对象,只是行为不同,也就是方法不同.那执行不同的方法时要遵循不同的定律.如果用OO的思想我们把定律抽象为对象,则定律起作用就是定律对象的方法被调用.同一个”人”对象,在调用不同的方法时,要明确什么定律起主要作用,就必须要把相应定律接口申明到自己方法体中去.这样就形成了耦合!当然使用Design Pattern能将这种耦合变成松耦合,如使用Observer模式,但即使这样也会有很多的问题:如果同时多个定律起作用,或定律起作用有先后顺序,或这些定律没法形成一个统一的父类接口……还有observer模式其实也是主动的模式,它依赖于对象要主动notify这些observer.
更有意思的是,如果一只鸡或一只鸭从楼上掉下去,它也要遵守万有引力定律和牛顿定律,而且计算方式与人完全一样.如果用OOP的思想,一是使用继承,定义一个父类,由它实现高处落下时的逻辑,这样子类就可以自动获得这些逻辑,但这样势必将因为影响行为的定律的复杂性,而带来类层次的复杂性;二是使用代理,东西由高处落下就交给一个delegate对象去处理,而这样需要多少种delegate对象,每用一个delegate对象,就意味着当前对象耦合了一个delegate对象,结果对象的耦合性越来越强.
那么换个角度想,如果真有一个上帝,它监控着所有的对象,只要某一个对象从高处落下,它就把万有引力定律和牛顿定律用到这个对象身上,而不管这个对象是否知道这两个定律.这样对象与这两个定律完全解耦合,它只管做自己的事,比如一个人从窗台跳下去, 万有引力定律和牛顿定律也起作用,但他没有什么损伤,接着就骑辆车上街去了……上街是这个人的主要目的,跳窗台也许是为图一时方便,下次他也许就不跳了.但只要他跳了,就得由上帝用万有引力定律和牛顿定律计算一下,如果窗台很高,计算结果或许就是他骨折了,只能躺医院去.这个上帝就是自然规律.我们可能感觉不到它的存在,但它确实在那里,只要条件被触发,它就会起作用,不依赖于任何个体.
AOP正是这个上帝在程序世界的体现.一个Aspect就是一条定律或规范及其执行策略.对普适定律而言,他对所有系统中的对象起作用.而一些法律,比如未成年人法就只对未成年人起作用,一些规定比如车辆经过收费站要收费,却对公车无效.一个Aspect的pointcut就类似这些定律或法律或规定起作用的条件,它能确定对象的范围,对象的行为,并将一些特权阶级,特权行为剔除出去.而advice就是他们的执行了.
对AOP的具体语法,我不想涉及,大家很容易找到资料.我希望的是能有很多的人谈谈自己对AOP的认识,我的观点也许也很片面,希望通过讨论更加的完善.