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