1、引言
筆者在使用Visual FoxPro 6.0編制超市綜合信息管理系統(tǒng)時,由于某些參數(shù)的設(shè)置不當,或某些命令使用不當,曾走過一些彎路,總結(jié)起來體會頗多。
2、Visual FoxPro 6.0的幾個不盡如意的地方
2.1 Visual FoxPro 6.0的一個bug
筆者在設(shè)計一個產(chǎn)品庫存查詢表單(form)kccx.scx時,其中一個網(wǎng)格(grid)grid1顯示查詢內(nèi)容,運行此表單,因尚未選擇查詢條件,網(wǎng)格顯示所有產(chǎn)品的庫存情況。因此,在表單kccx.scx的active事件中加入以下程序,使網(wǎng)格grid1顯示表dspbmk(產(chǎn)品庫存庫)的全部內(nèi)容:
select * from dspbmk into table tj
thisform.grid1.recordsource="tj"
thisform.grid1.scrollbars=3
thisform.refresh
系統(tǒng)剛開始運行時,由于產(chǎn)品記錄個數(shù)少并未發(fā)現(xiàn)問題,但隨著產(chǎn)品的增加,發(fā)現(xiàn)進入此表單很慢。通過將SET SAFETY 設(shè)置為ON,單步調(diào)試,發(fā)現(xiàn)上述程序的第一條SELECT語句重復(fù)執(zhí)行若干次。將此段程序移到表單的init事件后,程序執(zhí)行正常;蛘邔⑸隙纬绦蛟摓椋
select * from dspbmk into cursor tj
thisform.grid1.recordsource="tj"
thisform.grid1.scrollbars=3
thisform.refresh
程序也執(zhí)行正常。
同樣,將上段程序放入頁框(pageframe)的某一頁(page)的active事件中,也會出現(xiàn)同樣的問題。筆者并未找到關(guān)于此問題解釋的相關(guān)資料,也許這是Visual FoxPro 6.0的一個bug。
2.2 慎用VFP的緩沖區(qū)功能
Visual FoxPro 6.0提供了緩沖區(qū)功能,只要將緩沖區(qū)(buffering)狀態(tài)設(shè)為2、3、4、5,那么對表或記錄的操作只在緩沖區(qū)中進行,再通過tableupdate()函數(shù)將修改傳送到表中,或通過tablerevert()函數(shù)取消對表的修改。VFP的這種功能大大簡化了程序的編寫。但提醒編程者注意:當使用表緩沖(buffering狀態(tài)設(shè)為5)功能時,若一次修改的記錄數(shù)太多(比如400條以上),當執(zhí)行tableupdate()函數(shù)對表進行真正修改時,發(fā)現(xiàn)緩沖區(qū)的數(shù)據(jù)丟失,本次修改失敗。
2.3 多使用FLUSH命令
假定有一表單,要連續(xù)執(zhí)行若干小時,其中經(jīng)常要對某個表操作,在表單的load事件中打開此表,此后該表一直處于打開狀態(tài),通過APPE、DELE、REPL等操作對表進行了上千條記錄的操作,但當退出后有時會發(fā)現(xiàn)當天的數(shù)據(jù)并未保存,盡管VFP幫助文件中介紹5分鐘后會自動FLUSH。在每次操作后加入FLUSH語句,再沒出現(xiàn)以上問題。
3、Visual FoxPro 6.0網(wǎng)絡(luò)程序設(shè)計應(yīng)注意的幾個問題
在單用戶狀態(tài)下,數(shù)據(jù)庫的使用沒有共享和獨占概念,用戶可以隨意對表進行增、刪、改、查等操作,不受任何影響。但是,在網(wǎng)絡(luò)環(huán)境下就不一樣,當表被打開時,如果兩個用戶對一個表同時進行修改、刪除等操作,后果將不堪設(shè)想。所以在網(wǎng)絡(luò)環(huán)境下表的打開有兩種方式:一是共享方式,表示這個表可以被任何用戶操作;二是獨占方式,表示這個表只能被一個用戶操作。例如,對于商場管理系統(tǒng),由于數(shù)據(jù)量大,需經(jīng)常對表進行數(shù)據(jù)整理(需執(zhí)行PACK、ZAP等操作),當系統(tǒng)管理員進行數(shù)據(jù)整理時表必須以獨占方式打開;而前臺收款和后臺操作同時進行時,表必須以共享方式打開。那么如何解決多個用戶同時對表操作而不致出現(xiàn)問題呢?下面筆者談幾點體會。
3. 1 一般的解決方法
文件或記錄的加鎖與解鎖是網(wǎng)絡(luò)程序設(shè)計中經(jīng)常用到的方法。VFP提供了FLOCK()、RLOCK()和LOCK()函數(shù)對文件和記錄進行加鎖,一個文件或記錄加鎖后,只能由加鎖用戶進行讀寫,其他用戶只能讀不能寫。當對記錄或文件進行修改或刪除時,必須加鎖。當對文件操作完畢應(yīng)及時解鎖,VFP提供UNLOCK命令對指定工作區(qū)解鎖。如:
do while !flock()
wait window ‘正在鎖定數(shù)據(jù)庫請稍候!’Timeout 0.05
enddo
:
unlock
當對文件或記錄加鎖時,若由于某種原因沒有鎖住,可以再試加鎖操作,并可指定加鎖次數(shù)或試鎖的時間。VFP提供了SET REPROCESS TO命令來確定如何控制失敗的記錄或文件加鎖。此外,VFP還提供SET REFRESH TO命令控制多長時間后顯示網(wǎng)絡(luò)中其他用戶對記錄所做的修改。
3.2 慎用VFP的隱含鎖定功能
當VFP處于隱含鎖定狀態(tài)(即SET LOCK 設(shè)置為ON)時,執(zhí)行某些命令時將自動對表加鎖。這些命令包括:
AVERAGE、CALCULATE、LIST、DISPLAY、SORT、INDEX、COUNT、TOTAL、SUM、COPY TO、COPY TO ARRAY 、REPORT、JOIN、LABEL。
在網(wǎng)絡(luò)環(huán)境中,必須將SET LOCK 設(shè)置為OFF,以免影響其他用戶的正常使用。例如,一個商場管理系統(tǒng),后臺正在打印商品信息,若SET LOCK 設(shè)置為ON,則此時商品信息表將加鎖,前臺銷售需對商品信息表的商品庫存進行減操作,也需對商品信息表加鎖。此時將陷入鎖定等待狀態(tài),影響前臺收款。
3.3 使用VFP的多記錄鎖功能時要及時對記錄開鎖
Visual FoxPro 6.0將SET MULTILOCKS設(shè)置為ON,即設(shè)置多記錄鎖,表示同時對多條記錄加鎖。對此功能的使用需謹慎,一定要及時開鎖,否則容易引起死鎖。假定有一個網(wǎng)絡(luò)版的商場銷售系統(tǒng),許多表單的對表操作采用了表緩沖區(qū)狀態(tài),由于VFP規(guī)定使用緩沖區(qū)功能必須將SET MULTILOCKS設(shè)置為ON。所以系統(tǒng)運行時是處于多鎖狀態(tài)。前臺銷貨存盤時要對商品信息表(dspbmk.dbf)中的商品庫存量進行修改,在存盤按鈕的click事件中加入以下程序段:
sele sp /* 銷售商品清單
go top
do while .not. eof()
sele dspbmk
seek sp.spbh
do while !rlock()
wait window ‘正在鎖定數(shù)據(jù)庫請稍候!’Timeout 0.05
enddo
repl kcl with kcl-sp.sl
sele sp
skip
enddo
sele dspbmk
unlock in dspbmk
程序?qū)γ總記錄修改后并未及時開鎖,在全部修改完后才開鎖。
假定有甲乙兩個收款臺,前臺甲正在賣編號為1、2、3的商品,前臺乙正在賣編號為3、2、1的商品,甲存盤時首先鎖定1商品,庫存量修改完后記錄指針移動,又鎖定了2商品的記錄,處理完后試圖鎖定2商品;而前臺先鎖定了3商品記錄,處理完后試圖鎖定2商品。這時就發(fā)生死鎖,造成系統(tǒng)癱瘓。糾其原因,主要因為SET MULTILOCKS設(shè)置為ON了,而以上程序卻未對記錄及時開鎖。