今天負責把多個系統的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.tkk7.com/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的認識,我的觀點也許也很片面,希望通過討論更加的完善.