實際業務中碰到了PB開發的業務系統造成的數據死鎖情況,整理了一些PB關於數據庫死鎖的一些處理。
PB死鎖相關
1. 即時的commit和rollback
不同數據庫的鎖機制各不相同,但對應用程序來說,造成死鎖的最大可能就是:沒有養成對每個 COMMIT 的執行結果進行檢查的編碼習慣,導致提交出錯時未能及時 ROLLBACK 造成死鎖。
示例代碼:
sqlca.autocommit=false //一定要設置為不自動提交
string ls_err
dec ldec_xxx
select column_xxx into :ldec_xxx from TABLE_yyy where id=keyvalue; //如果有必要查詢當前值的話.
if sqlca.sqlcode <0 then
ls_err=sqlca.sqlerrtext //先讀錯誤信息,然后立即ROLLBACK再提示,以免提示時用戶不確定,表還在鎖定中
rollback; //立即回滾,以免其它用戶等待.
messagebox("提示","數據庫發生以下錯誤:~n"+ls_err)
return
end if
commit using sqlca;
2. sqlca.autocommit(參考)
在使用有增、刪、改的語句時在前邊加鎖、更改完畢后解鎖即可:
sqlca.autocommit=true
insert.......
update .......
delete......等語句
sqlca.autocommit=false
3. 用DataWindow操作的話:
1)Dw的Specify Update Characteristics屬性:
設置DW的Specify Update Characteristics為: (3)Key and Modified Columns
這樣,只要你更新的列的值沒有變,則大家都可以成功,有效的防止了多用戶重疊更新的問題,相當安全,不必使用第二選項.
2)數據窗口的RetrieveEnd事件
在數據窗口的Retrieveend事件的腳本中加COMMIT USING SQLCA;
呵呵,PB是有這個問題,以前給別個說的時候有些人還不信。你可以在數據窗口的RetrieveEnd事件里面加上一句“commit;”就OK了。個人認為是數據窗口在檢索出數據后仍然占據着相應的表資源,直到提交數據為止才會釋放,也就是結束本次事務,開始新的事務。PB這樣做可能是為了保證數據的完整性,使用我說的解決辦法,經測試沒有發現什么問題,但是也不能保證完全沒問題,有問題的話也是出在數據庫的並發控制上,有興趣自己去測試一下嘛。
4. SQLCA.LOCK屬性(RC或RU)
設置sqlca.lock='RU',這樣的缺陷是降低了讀取數據的安全級別。
示例代碼:
// Profile iadserver
SQLCA.DBMS = "OLE DB"
SQLCA.LogPass =profilestring('dbms.ini' , "database" , "logpass" , "")
SQLCA.LogId = profilestring('dbms.ini', "database" , "logid" , "")
SQLCA.AutoCommit = False
SQLCA.Lock='RC'
SQLCA.DBParm = "PROVIDER='SQLOLEDB',"+&
"DATASOURCE='" + profilestring('dbms.ini' , "database" , "serverip" , "") + "'," +&
"PROVIDERSTRING='Database="+profilestring('dbms.ini' , "database" , "dbname" , "")+"'"
connect using sqlca ;
if SQLCA.SQLCode <> 0 then
messagebox("提示信息:", '連接數據庫出錯!' + SQLCA.SQLErrText , stopsign!)
rollback using sqlca ;
halt close
end if