今天改完了bug就開始考慮起怎么優(yōu)化數(shù)據(jù)導(dǎo)入的程序了。我們的系統(tǒng)構(gòu)架要求客戶端不能執(zhí)行sql語(yǔ)句,所有的數(shù)據(jù)庫(kù)操作都要通過ejb來(lái)實(shí)現(xiàn)。我這個(gè)數(shù)據(jù)導(dǎo)入就麻煩了,因?yàn)槭谴罅繑?shù)據(jù)的導(dǎo)入,如果采用ejb的方式一條一條的導(dǎo)入,速度會(huì)很慢。
所以我采取了定義一個(gè)SessionBean,在SessionBean中定義一個(gè)executeSQL方法,接受兩個(gè)參數(shù),一個(gè)是sql語(yǔ)句(可能帶參數(shù)),和一個(gè)參數(shù)值數(shù)組。這樣客戶端就可以直接通過sql語(yǔ)句操縱數(shù)據(jù)庫(kù)了。但是問題也就來(lái)了,如果每條數(shù)據(jù)都調(diào)用executeSQL訪問一次數(shù)據(jù)庫(kù),這樣不僅會(huì)造成頻繁的事務(wù)啟動(dòng),速度很慢,而且由于各個(gè)數(shù)據(jù)庫(kù)插入操作之間是在不同的ejb調(diào)用中進(jìn)行的,所以無(wú)法保證事務(wù)。我優(yōu)化的重點(diǎn)當(dāng)然也就在這兩點(diǎn)上。項(xiàng)目緊急,我不能對(duì)構(gòu)架做太大的改動(dòng)了,因?yàn)楫吘挂郧暗膶?shí)現(xiàn)方式可以導(dǎo)入數(shù)據(jù)了,我就琢磨著在不做大規(guī)模改動(dòng)的情況下進(jìn)行優(yōu)化,將風(fēng)險(xiǎn)降低到最小。
系統(tǒng)中所有ejb都是基于接口的,比如上邊定義的executeSQL方法就定義在IImportDataFacade接口中,ejb實(shí)現(xiàn)這個(gè)接口,客戶端通過工廠方法ImportDataFactory.getInstance()訪問這個(gè)接口(ImportDataFactory.getInstance()返回IImportDataFacade類型)。好,我就從他下手。定義一個(gè)ImportDataDecorate類,讓他也實(shí)現(xiàn)IImportDataFacade接口,它的executeSQL實(shí)現(xiàn)不是吧sql提交到數(shù)據(jù)庫(kù),而是把它緩存起來(lái),等所有插入語(yǔ)句執(zhí)行完畢后將緩存的sql語(yǔ)句一次性提交到我定義的一個(gè)新的接口方法中(此方法含有一個(gè)sql數(shù)組的發(fā)那個(gè)法),這樣就可以保證事務(wù)和速度了。
我是怎么實(shí)現(xiàn)對(duì)系統(tǒng)改動(dòng)最小呢?對(duì)了,我只要把所有調(diào)用ImportDataFactory.getInstance().executeSQL()的地方替換成new ImportDataDecorate(ImportDataFactory.getInstance()).executeSQL(),哈哈,改動(dòng)很小吧,而且一旦發(fā)現(xiàn)這種實(shí)現(xiàn)方式不可行,那么只要將ImportDataDecorate.executeSQL()的實(shí)現(xiàn)改成直接提交到數(shù)據(jù)庫(kù)就好了,其他調(diào)用根本不用變。設(shè)計(jì)模式很偉大呀,只不過我都不知道我用的這是什么模式,Proxy 還是Decorator?不知道,反正解決問題了,呵呵。