多線程(MultiThread)+BDE+Oracle database 頻繁出錯(ORA-12560,ORA-03113) |
答題得分者是:carstyc
|
dust.zhu
一般會員 ![]() ![]() 發表:3 回覆:8 積分:2 註冊:2009-06-30 發送簡訊給我 |
環境描述
OS:WINDOWS XP DEVELOP TOOL:DELPHI 6.0 BDE Ver:5.01 Oracle client:ver 8.1.7 Oracle DB:9i newwok:PL LAN--switch-firwall-Company LAN--db server(Run on sun SOLARIS) 程式描述: 物料驗證與追蹤系統(SMT PVS&PTS) 主程序用來上料,確認,檢驗 線程1:PTS,物料追溯,link sn,reel,扣reel料數量 線程2:PVS,驗證是否缺料,多料,錯料 線程3:採用FTP讀取SPI,AOI的測試資料,收集SN資訊; 每個線程都按delphi推薦的模式;擁有獨立的database,session 問題描述: 程式運行一段時間後有報如下錯誤: ------------------------------------------------------------------------------- 以”ORA-12560: TNS:協定介面程式錯誤”為主;其他還有 ”ORA-12571: TNS:封包寫入器失敗”; ”ORA-03114: 未與 ORACLE 相連” ------------------------------------------------------------------------------- 平均1個多小時出一次錯誤;最長4個小時 出錯後程式有自動關閉資料庫database.close,但錯誤依舊迴圈; 關閉application後再開啟OK,運行一段時間錯誤重現 期間TNSPING DB正常 有請DBA查看dbServer log沒有發現類似錯誤 有請網路管理員查看switch,firewall;沒發現對應的錯誤,流量也在可接受範圍內(1M/PER PC) ×××××××××××××××××××××××××××××××××××××××××××××××××××× 為了找尋問題的根源,有寫一支小程式(類比PTS,3個線程一個主程序;資料量要比PTS少很多),不斷的隨機往database裏面insert,select,delete資料 抽取了24小時內的log 結果有出現5次中斷,最長間隔12小時,最短0.5小時:每次的錯誤順序為:(與PTS的錯誤有些差異) ------------------------------------------------------------------------------- Lost communication with SQL server.ORA-03113: 通訊通道上出現 EOF General SQL error. ORA-03114: 未與 ORACLE 相連 ------------------------------------------------------------------------------ 但同時段卻沒有對應的ping丟包現象且此程序出錯的時間和PTS程序的錯誤時間也不匹配,可以排出網路的問題! 難道BDE多線程在資料量大且頻繁作業(每秒可能有上百筆資料要處理)的時候及其不穩定?google了下也沒發現類似的問題! 盼望高手能給與指點!!萬分感謝! 編輯記錄
dust.zhu 重新編輯於 2009-07-03 09:02:06, 註解 無‧
|
frappe
中階會員 ![]() ![]() ![]() 發表:88 回覆:114 積分:95 註冊:2008-10-21 發送簡訊給我 |
同一個Query如果需要24小時不斷執行,
需要釋放記憶體,不然程式容易當掉 這個是之前去資策會上課,老師教的, 試試看吧,希望對你有用^^ 迴圈..... Query1.Prepared:=false; Query1.Prepared:=true; Query1.Close; ........ Query1.Open; |
dust.zhu
一般會員 ![]() ![]() 發表:3 回覆:8 積分:2 註冊:2009-06-30 發送簡訊給我 |
十分感謝frappe的答復!前兩天有休假沒及時回復!
程序中的tquery確實沒用到close,基本都是 query.SQL.Clear; query.SQL.Add(''..); query.ParamByName('..').AsString :=..; ...................................... query.Open/.ExecSQL; 但delphi幫助文檔有這樣的語句: “When you change the text of a query at runtime, the query is automatically closed and unprepared.” 所以鄙人認為可以不寫close,prepare代碼, 在調用query.sql.clear時系統會自動做這個動作;不知理解是否有誤? 這個問題現在依舊沒有解決,出了這種錯誤,產線只能關了程序再開,很讓人頭疼! 希望有前輩高人能指點,小弟不勝感激!
編輯記錄
dust.zhu 重新編輯於 2009-07-03 08:57:04, 註解 無‧
|
GrandRURU
站務副站長 ![]() ![]() ![]() ![]() ![]() ![]() 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
建議你可以更新
bde及oracle client的版本,或許可以直接解決你的問題 另外,針對你所說的錯誤訊息,我在其它的網站上有看到類似的解決做法 http://www.itpub.net/viewthread.php?tid=124145 你可以參考看看 ===================引 用 dust.zhu 文 章=================== 環境描述 OS:WINDOWS XP DEVELOP TOOL:DELPHI 6.0 BDE Ver:5.01 Oracle client:ver 8.1.7 Oracle DB:9i newwok:PL LAN--switch-firwall-Company LAN--db server(Run on sun SOLARIS) 程式描述: 物料驗證與追蹤系統(SMT PVS&PTS) 主程序用來上料,確認,檢驗 線程1:PTS,物料追溯,link sn,reel,扣reel料數量 線程2:PVS,驗證是否缺料,多料,錯料 線程3:採用FTP讀取SPI,AOI的測試資料,收集SN資訊; 每個線程都按delphi推薦的模式;擁有獨立的database,session 問題描述: 程式運行一段時間後有報如下錯誤: ------------------------------------------------------------------------------- 以”ORA-12560: TNS:協定介面程式錯誤”為主;其他還有 ”ORA-12571: TNS:封包寫入器失敗”; ”ORA-03114: 未與 ORACLE 相連” ------------------------------------------------------------------------------- 平均1個多小時出一次錯誤;最長4個小時 出錯後程式有自動關閉資料庫database.close,但錯誤依舊迴圈; 關閉application後再開啟OK,運行一段時間錯誤重現 期間TNSPING DB正常 有請DBA查看dbServer log沒有發現類似錯誤 有請網路管理員查看switch,firewall;沒發現對應的錯誤,流量也在可接受範圍內(1M/PER PC) 為了找尋問題的根源,有寫一支小程式(類比PTS,3個線程一個主程序;資料量要比PTS少很多),不斷的隨機往database裏面insert,select,delete資料 抽取了24小時內的log 結果有出現5次中斷,最長間隔12小時,最短0.5小時:每次的錯誤順序為:(與PTS的錯誤有些差異) ------------------------------------------------------------------------------- Lost communication with SQL server.ORA-03113: 通訊通道上出現 EOF General SQL error. ORA-03114: 未與 ORACLE 相連 ------------------------------------------------------------------------------ 但同時段卻沒有對應的ping丟包現象且此程序出錯的時間和PTS程序的錯誤時間也不匹配,可以排出網路的問題! 難道BDE多線程在資料量大且頻繁作業(每秒可能有上百筆資料要處理)的時候及其不穩定?google了下也沒發現類似的問題! 盼望高手能給與指點!!萬分感謝! |
dust.zhu
一般會員 ![]() ![]() 發表:3 回覆:8 積分:2 註冊:2009-06-30 發送簡訊給我 |
|
frappe
中階會員 ![]() ![]() ![]() 發表:88 回覆:114 積分:95 註冊:2008-10-21 發送簡訊給我 |
你可以不寫Close,
但是Prepare一定要寫, 因為這是用在資料庫最佳化與清除記憶體 ===================引 用 dust.zhu 文 章=================== 十分感謝frappe的答復!前兩天有休假沒及時回復! 程序中的tquery確實沒用到close,基本都是 query.SQL.Clear; query.SQL.Add(''..); query.ParamByName('..').AsString :=..; ...................................... query.Open/.ExecSQL; 但delphi幫助文檔有這樣的語句: “When you change the text of a query at runtime, the query is automatically closed and unprepared.” 所以鄙人認為可以不寫close,prepare代碼, 在調用query.sql.clear時系統會自動做這個動作;不知理解是否有誤? 這個問題現在依舊沒有解決,出了這種錯誤,產線只能關了程序再開,很讓人頭疼! 希望有前輩高人能指點,小弟不勝感激! |
GrandRURU
站務副站長 ![]() ![]() ![]() ![]() ![]() ![]() 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
|
dust.zhu
一般會員 ![]() ![]() 發表:3 回覆:8 積分:2 註冊:2009-06-30 發送簡訊給我 |
|
GrandRURU
站務副站長 ![]() ![]() ![]() ![]() ![]() ![]() 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
|
carstyc
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:16 回覆:254 積分:329 註冊:2003-07-18 發送簡訊給我 |
請教一下,你說你的 Thread 都有獨立的 Database 跟 Session 。
但你的 Thread 是持續跑很長的一段時間? 還是每跑完一個動作,Thread 就 Free 掉了。等要做下一個動作時再起另一個新的Thread。 如果是跑完一個動作就 Free 掉,就沒有 Close 不 Close 或是 要不要 Prepare 的問題,因為你連 Thread 都釋放掉了,當然下一個Thread再起來的時候,就會有新的 DataBase 來建立新的 Connection了。 如果不是,而是一個Thread 持續跑很久,這時就有可能會有你說的這些問題。 我不確定你的Thread寫法是如何,但DB 會有某些設定,會影響到你的AP。 舉個例來說,DB會把某些Connection 太久沒有做動作,而把它視為異常,進而主動把它『幹掉』。讓資源回收,可再給別的AP使用。 比如(我猜測的), 你的Thread 見到現在沒事做,就休息個幾十分鐘,或更久,等到下一次要再去檢查有沒有事要做的時候,Connection 卻被 DB主動砍掉了,所以你的AP就有可能出現 這些錯誤訊息。 甚至我碰過另一個情況,我用一個大迴圈把要做的項目列出來,然後根據大迴圈的資料去跑小迴圈做運算,結果小迴圈因為筆數較多,運算較久,而此時大迴圈的 Connection 都沒動作,且超過一定時間,而 AP 就有 Excepion 跑出來了,因為DB認為這個Connection 太久沒動作,就把把它回收去了。此時,即時去DB看Error也不會有看到異常的log,因為這個動作屬於『正常回收作業』。 以上方向提供你參考,我覺得你的問題點應該也是類似,只是我不知道你Thread的運作方法為何? 無法幫你Debug。你自己再找找看。 對了,順帶提一下解決方式,如果你有 DBA的權限,就找到那個 Time out 時間的參數,把它調高。 如果沒有DBA權限,只能靠自己改AP的話,就只好定時去把Connection 做些動作,比如定時就去Select 某個最小的Table。只要讓Connection 有動作,DB就不會把它『幹掉』了... ===================引 用 dust.zhu 文 章=================== 環境描述 OS:WINDOWS XP DEVELOP TOOL:DELPHI 6.0 BDE Ver:5.01 Oracle client:ver 8.1.7 Oracle DB:9i newwok:PL LAN--switch-firwall-Company LAN--db server(Run on sun SOLARIS) 程式描述: 物料驗證與追蹤系統(SMT PVS&PTS) 主程序用來上料,確認,檢驗 線程1:PTS,物料追溯,link sn,reel,扣reel料數量 線程2:PVS,驗證是否缺料,多料,錯料 線程3:採用FTP讀取SPI,AOI的測試資料,收集SN資訊; 每個線程都按delphi推薦的模式;擁有獨立的database,session 問題描述: 程式運行一段時間後有報如下錯誤: ------------------------------------------------------------------------------- 以”ORA-12560: TNS:協定介面程式錯誤”為主;其他還有 ”ORA-12571: TNS:封包寫入器失敗”; ”ORA-03114: 未與 ORACLE 相連” ------------------------------------------------------------------------------- 平均1個多小時出一次錯誤;最長4個小時 出錯後程式有自動關閉資料庫database.close,但錯誤依舊迴圈; 關閉application後再開啟OK,運行一段時間錯誤重現 期間TNSPING DB正常 有請DBA查看dbServer log沒有發現類似錯誤 有請網路管理員查看switch,firewall;沒發現對應的錯誤,流量也在可接受範圍內(1M/PER PC) חחחחחחחחחחחחחחחחחחחחחחחחחח 為了找尋問題的根源,有寫一支小程式(類比PTS,3個線程一個主程序;資料量要比PTS少很多),不斷的隨機往database裏面insert,select,delete資料 抽取了24小時內的log 結果有出現5次中斷,最長間隔12小時,最短0.5小時:每次的錯誤順序為:(與PTS的錯誤有些差異) ------------------------------------------------------------------------------- Lost communication with SQL server.ORA-03113: 通訊通道上出現 EOF General SQL error. ORA-03114: 未與 ORACLE 相連 ------------------------------------------------------------------------------ 但同時段卻沒有對應的ping丟包現象且此程序出錯的時間和PTS程序的錯誤時間也不匹配,可以排出網路的問題! 難道BDE多線程在資料量大且頻繁作業(每秒可能有上百筆資料要處理)的時候及其不穩定?google了下也沒發現類似的問題! 盼望高手能給與指點!!萬分感謝! |
dust.zhu
一般會員 ![]() ![]() 發表:3 回覆:8 積分:2 註冊:2009-06-30 發送簡訊給我 |
感謝carstyc的回復
datamodule中有對應線程的database,session且每個線程只有一對;database.sessionname:=Session.sessionname, thread執行在一個迴圈中,會持續跑很長的時間,因此不存在“太久沒有做動作”這個問題 線程的邏輯大概如下,這個線程的tquery是自動創建,其它兩個線程引用了datamodule中的tquery [code delphi] procedure TPTSThread.Execute; const C_SECOND = 1 / 8640;//10s begin { Place thread code here } try try {建立線程和ADO組件的關系(線程中有用到一個自動創建的ado組件, 僅用于讀取本地access database中的數據)} CoInitialize(nil); //初始化系統參數 IniParameters; while True do begin try if FNextProcessTime < Now then begin //如果線程中止,跳出循環 if Terminated then Break; //當前此指針函數為空;DoBeforeProcessed:=nil; if Assigned(DoBeforeProcessed) then Synchronize(DoBeforeProcessed); //check Process執行的條件是否滿足 if CheckInputs then begin //如果線程中止,跳出循環 if Terminated then Break; {主處理邏輯;link sn,reel;扣減reel當前數量;如果reel數量耗完則下架, 如果此reel有接料(備用reel),上架接料reel(參與link sn,reel,扣減數量) 此邏輯用的tdatabase來源于datamodule,在線程create時作參數傳入; 其它所有的tquery全部在線程create內部自動創建} Process; end; FNextProcessTime := NOW C_SECOND; //當前此指針函數為空;DoAfterProcessed:=nil; if Assigned(DoAfterProcessed) then Synchronize(DoAfterProcessed); //如果線程中止,跳出循環 if Terminated then Break; end else Sleep(C_MILLISECOND);//等待200毫秒;釋放cpu //如果線程中止,跳出循環 if Terminated then Break; except on e: Exception do begin FUserMessages := e.Message; //如果有出現“ora-...”等database連接的錯誤,close database if IsDBException(FUserMessages) then FDBOracle.Close;//此處FDBOracle引用了datamodule中的database //顯示給用戶系統異常信息,不需要用戶確認 FDialogType := dtNoDialog; Synchronize(MessagesToUser); end; end; end; except on e: Exception do begin //顯示給用戶系統異常信息,需要用戶確認 FUserMessages := e.Message; FDialogType := dtConfirmDialog; Synchronize(MessagesToUser); end; end; finally //釋放資源 FreeResource; CoUninitialize; end; end; [/code] |
carstyc
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:16 回覆:254 積分:329 註冊:2003-07-18 發送簡訊給我 |
看了一下你的程式,主要的 DB 運作應該是在 DoBeforeProcessed 跟 DoAfterProcessed
但實際上還是不太清楚這兩個procedure的內部動作為何? 而你說的 thread執行在一個迴圈中,會持續跑很長的時間,因此不存在“太久沒有做動作”這個問題 ,我再跟你解釋一下 Thread 的迴圈是無窮迴圈,除非你下 Terminated =true 才會結束,但不代表在迴圈內的 Connection 就一定會有動作。 我舉個實際的例子 [code cpp] while not query1.eof do begin while not query2.eof do begin query2.next; end; query1.next; end; [/code] 當上面的例子,如果 query1 與 query2 屬於兩個不同的connection 時,而query2 的迴圈運作時,其實query1的connection 是『沒有動作』的.... 當query2的迴圈跑超過一定時間後,DB會主動把query1 的 connection 砍掉, 而query2跑完時,它就會去跑 query1.next; , 而此時就會有 Exception 跑出來了。 但整個 process 是在一個大迴圈中跑,也就是你講的 thread執行在一個迴圈中,會持續跑很長的時間 但不保証所有的 Connection 是一定『有動作』的。 以上說明,請參考 ===================引 用 dust.zhu 文 章=================== 感謝carstyc的回復 datamodule中有對應線程的database,session且每個線程只有一對;database.sessionname:=Session.sessionname, thread執行在一個迴圈中,會持續跑很長的時間,因此不存在“太久沒有做動作”這個問題 線程的邏輯大概如下,這個線程的tquery是自動創建,其它兩個線程引用了datamodule中的tquery [code delphi] procedure TPTSThread.Execute; const C_SECOND = 1 / 8640;//10s begin { Place thread code here } try try {建立線程和ADO組件的關系(線程中有用到一個自動創建的ado組件, 僅用于讀取本地access database中的數據)} CoInitialize(nil); //初始化系統參數 IniParameters; while True do begin try if FNextProcessTime < Now then begin //如果線程中止,跳出循環 if Terminated then Break; //當前此指針函數為空;DoBeforeProcessed:=nil; if Assigned(DoBeforeProcessed) then Synchronize(DoBeforeProcessed); //check Process執行的條件是否滿足 if CheckInputs then begin //如果線程中止,跳出循環 if Terminated then Break; {主處理邏輯;link sn,reel;扣減reel當前數量;如果reel數量耗完則下架, 如果此reel有接料(備用reel),上架接料reel(參與link sn,reel,扣減數量) 此邏輯用的tdatabase來源于datamodule,在線程create時作參數傳入; 其它所有的tquery全部在線程create內部自動創建} Process; end; FNextProcessTime := NOW C_SECOND; //當前此指針函數為空;DoAfterProcessed:=nil; if Assigned(DoAfterProcessed) then Synchronize(DoAfterProcessed); //如果線程中止,跳出循環 if Terminated then Break; end else Sleep(C_MILLISECOND);//等待200毫秒;釋放cpu //如果線程中止,跳出循環 if Terminated then Break; except on e: Exception do begin FUserMessages := e.Message; //如果有出現“ora-...”等database連接的錯誤,close database if IsDBException(FUserMessages) then FDBOracle.Close;//此處FDBOracle引用了datamodule中的database //顯示給用戶系統異常信息,不需要用戶確認 FDialogType := dtNoDialog; Synchronize(MessagesToUser); end; end; end; except on e: Exception do begin //顯示給用戶系統異常信息,需要用戶確認 FUserMessages := e.Message; FDialogType := dtConfirmDialog; Synchronize(MessagesToUser); end; end; finally //釋放資源 FreeResource; CoUninitialize; end; end; [/code] |
dust.zhu
一般會員 ![]() ![]() 發表:3 回覆:8 積分:2 註冊:2009-06-30 發送簡訊給我 |
感謝carstyc及時回復
DoBeforeProcessed,DoAfterProcessed在當前的程序中邏輯為空,并沒有用到 Process中包含了數據處理的全部主邏輯;不只本機緩存dataset的利用,也包含了insert,delete,update,所以每10S左右connection一定會被使用 我們近期做了些測試;當連接database數據作業頻繁的時候,時間長了就會出現錯誤;當數據交易量增大到每s成百上千筆的時候,一旦出錯,90%的情況下connection就不能再被使用(即使關閉再開啟),除非整個application關閉 |
carstyc
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:16 回覆:254 積分:329 註冊:2003-07-18 發送簡訊給我 |
sorry , 漏看了一個 process
但你的 befroeprocessed 跟 afterprocessed 都有使用 Synchronize ,為啥單 process 沒有用 Synchronize 呢。 你要不要試看看吧 process 用 Synchronize 去執行。 雖然你的 Thread 應該是唯一的,但習慣上用到 vcl 的 TDatabase 跟 TSession ,還是習慣把它包起來,執行上應該會比較穩定。 另提供幾個作法你試看看 1. process 處理完成後,把 database close ,待下次又執行到process 時,才去把database開啟 2.用 Synchronize 去執行process 3.不要用 DataModule 的 Database ,直接在 Thread 的 Constructor 中去建立 TDataBase 及Session及所有的TQuery。 ===================引 用 dust.zhu 文 章=================== 感謝carstyc及時回復 DoBeforeProcessed,DoAfterProcessed在當前的程序中邏輯為空,并沒有用到 Process中包含了數據處理的全部主邏輯;不只本機緩存dataset的利用,也包含了insert,delete,update,所以每10S左右connection一定會被使用 我們近期做了些測試;當連接database數據作業頻繁的時候,時間長了就會出現錯誤;當數據交易量增大到每s成百上千筆的時候,一旦出錯,90%的情況下connection就不能再被使用(即使關閉再開啟),除非整個application關閉 |
dust.zhu
一般會員 ![]() ![]() 發表:3 回覆:8 積分:2 註冊:2009-06-30 發送簡訊給我 |
感謝carstyc的答復
由于Process是一個非常耗時的作業,如果用Synchronize(Process),thread將suspend,main thread將執行process邏輯, 這將導致界面freeze,用戶無法作業; 鄙人認為只有耗時非常短,且又和其它thread或main thread有資源共用的邏輯,才可用Synchronize,即可保證資源的安全性又不影響用戶 delphi幫助文檔有如下 “Data access components are thread-safe as follows: For BDE-enabled datasets, each thread must have its own database session component. The one exception to this is when you are using Access drivers, which are built using a Microsoft library that is not thread-safe. For dbDirect, as long as the vendor client library is thread-safe, the dbDirect components will be thread-safe. ADO and InterbaseExpress components are thread-safe. When using data access components, you must still wrap all calls that involve data-aware controls in the Synchronize method. Thus, for example, you need to synchronize calls that link a data control to a dataset by setting the DataSet property of the data source object, but you don抰 need to synchronize to access the data in a field of the dataset” 并沒有提到BDE是thread-safe,據我們近期的測試結果,開啟三個application,每個application開一個thread;運行一段時間,程序同樣會出問題
編輯記錄
dust.zhu 重新編輯於 2009-07-09 11:58:28, 註解 無‧
|
carstyc
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:16 回覆:254 積分:329 註冊:2003-07-18 發送簡訊給我 |
你說的沒錯,只有Thread在存取 Thread non safe 資源時,用Synchronize才可保證資源的安全性 。
不過這只是我好奇你的 process 沒有用 Synchronize 執行而已,不一定問題是發生在這點上面。 但你的問題,看起來就很像是 Connection 突然不見的樣子。 你現在需要的是先找出 Exception 的原因,找到原因再來針對問題點解決。 那你可以試看看,試著去 監看你 DB 上的 connection ,當你AP執行起來時,應該就會產生一個 Connection ID,你把 ID 記起來,然後當程式發生異常時,再去看一下 Connection ID 是否還存在,還是不見了。如果你的 AP 的 database 不會中途 close 的話,你的 connection ID 應該是不會變。 所以你可能需要另一個程式定時去撈取DB上的 connection information ,並紀錄供後續追蹤用。 先提供你另一個暫時解決方案,你之前有提到,若發生異常,即使 Database重新啟用也無法work,必需重啟 AP 如果暫時找不到問題解決方式的話,就用 flyup 大大 提供的方法,在你偵測到Exception 時,重新啟動自己 AP http://delphi.ktop.com.tw/board.php?cid=30&fid=72&tid=26009 ===================引 用 dust.zhu 文 章=================== 感謝carstyc的答復 由于Process是一個非常耗時的作業,如果用Synchronize(Process),thread將suspend,main thread將執行process邏輯, 這將導致界面freeze,用戶無法作業; 鄙人認為只有耗時非常短,且又和其它thread或main thread有資源共用的邏輯,才可用Synchronize,即可保證資源的安全性又不影響用戶 delphi幫助文檔有如下 “Data access components are thread-safe as follows: For BDE-enabled datasets, each thread must have its own database session component. The one exception to this is when you are using Access drivers, which are built using a Microsoft library that is not thread-safe. For dbDirect, as long as the vendor client library is thread-safe, the dbDirect components will be thread-safe. ADO and InterbaseExpress components are thread-safe. When using data access components, you must still wrap all calls that involve data-aware controls in the Synchronize method. Thus, for example, you need to synchronize calls that link a data control to a dataset by setting the DataSet property of the data source object, but you don抰 need to synchronize to access the data in a field of the dataset” 并沒有提到BDE是thread-safe,據我們近期的測試結果,開啟三個application,每個application開一個thread;運行一段時間,程序同樣會出問題
編輯記錄
carstyc 重新編輯於 2009-07-09 12:24:32, 註解 無‧
|
GrandRURU
站務副站長 ![]() ![]() ![]() ![]() ![]() ![]() 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
這個文檔大致上是說資料存取元件是俱備「Thread-safe」的,除了存取M$的ACCESS以外(主因在ACCESS的Driver上)。
所以如果是使用BDE元件的話,應該就可以不用考慮這方面的問題,除非真的有BUG。(但好像沒人沒應過這方面的問題) 既然有用到ACCESS,那要不要先將存取ACCESS的部份先取消呢? 這樣的話同步功能應該就可以取消了吧。 ===================引 用 dust.zhu 文 章=================== 由于Process是一個非常耗時的作業,如果用Synchronize(Process),thread將suspend,main thread將執行process邏輯, 這將導致界面freeze,用戶無法作業; 鄙人認為只有耗時非常短,且又和其它thread或main thread有資源共用的邏輯,才可用Synchronize,即可保證資源的安全性又不影響用戶 delphi幫助文檔有如下 “Data access components are thread-safe as follows: For BDE-enabled datasets, each thread must have its own database session component. The one exception to this is when you are using Access drivers, which are built using a Microsoft library that is not thread-safe. For dbDirect, as long as the vendor client library is thread-safe, the dbDirect components will be thread-safe. ADO and InterbaseExpress components are thread-safe. When using data access components, you must still wrap all calls that involve data-aware controls in the Synchronize method. Thus, for example, you need to synchronize calls that link a data control to a dataset by setting the DataSet property of the data source object, but you don抰 need to synchronize to access the data in a field of the dataset” 并沒有提到BDE是thread-safe,據我們近期的測試結果,開啟三個application,每個application開一個thread;運行一段時間,程序同樣會出問題 |
dust.zhu
一般會員 ![]() ![]() 發表:3 回覆:8 積分:2 註冊:2009-06-30 發送簡訊給我 |
好久無法進入這個論壇了,剛開始以為論壇關閉了或被大陸給和諧了!
想想純技術的論壇,應該不至于遭此下場,經過多方搜索,才發現改成HTTPS了,呵呵! ------------------------------------------------------------------------------------------------------------ 現在問題已經解決,經過一段時間的運行,再沒有發現錯誤! 此前確實讓我郁悶了好長時間,一直找不到解決的方法,上面又盯的緊,最后下了決心,把有關dababase操作的三個線程合成了一個,經過一段時間的log觀察,終于發現了問題所在 PTS線程中有一種消息必須要用戶確認,確認后才能繼續執行,如果用戶半小時或一個小時后確認,后續的database操作就會報錯;這種情況應該屬于database正常關閉connection 所以database server上看不到exception log,了解到這點就好辦了,如果用戶在規定時間內沒用確認消息,系統自動取消確認動作,以繼續執行 其它存在的問題 socket錯誤:如果在不同的線程里使用FTP,及其它的網絡協議函數,極有可能引發這種錯誤,可以用臨界區或合并線程解決;而且這種錯誤一發生可能會引發BDE的錯誤(這點未做驗證) 個人的一點總結: 如非特殊需要,盡量不要開多個子線程,既浪費database的connection資源,又會導致程序異常復雜,出了問題很難調試! 最后,鄙人十分感謝各位的回復, 特別感謝carstyc,您的回復切中要害! 謝謝! |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |