全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2535
推到 Plurk!
推到 Facebook!

請問關於資料庫執行語法時發生的問題?

答題得分者是:Stallion
macchen
初階會員


發表:66
回覆:102
積分:33
註冊:2006-07-07

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-07-23 11:51:31 IP:211.75.xxx.xxx 訂閱
各位好,請問一下,我手上有一支程式,在客戶端會同時被啟動,而在程式中,會需要對某一個table做select及update的語法,而目前的情況相當容易造成deadlock的問題產生,導致無法解鎖,而程式在執行時因為是即時insert資料的,而又需要同步做update的動作,請問各位有沒有什麼比較好的方式可以解決或避免掉deadlock的問題,目前我使用的方式是當要update資料時,將此語法包在stored procedure內執行,可是目前測試下,還是會有deadlock的問題發生(雖然會解鎖),但仍覺的穩定性不夠,如果在客戶端當網路或server busy時,可能會造成鎖無法解開,而軟體會產生「逾時過期」的問題,在論壇上是有看到下flag的動作,想請問一下,有沒有什麼辦法可以解決此問題,謝謝各位。

我的開發環境是delphi 7 ms sql server 2000
------
DELPHI初學者
編輯記錄
macchen 重新編輯於 2007-07-23 11:52:16, 註解 無‧
pedro
尊榮會員


發表:152
回覆:1187
積分:892
註冊:2002-06-12

發送簡訊給我
macchen
初階會員


發表:66
回覆:102
積分:33
註冊:2006-07-07

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-07-26 17:13:07 IP:211.75.xxx.xxx 訂閱
謝謝你的回覆,大致上有概念,我也是使用包在tran中去執行,但是在執行中,雖然db會自動作排程,可是如果個client連線超過30(預設timeout都是30s),那麼就有可能還是會有些client端無法取得資源而產生timeout,想請問一下,因為我在執行tran中會常常會使用到update,那麼我該如何使用才可達到row lock的模式,對於這方面還是不清楚,可否請大大舉個例子,謝謝你。


===================引 用 pedro756901 文 章===================
參考這裡
http://delphi.ktop.com.tw/board.php?cid=30&fid=66&tid=38491
http://delphi.ktop.com.tw/board.php?cid=30&fid=66&tid=61395
------
DELPHI初學者
Stallion
版主


發表:52
回覆:1600
積分:1995
註冊:2004-09-15

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-07-26 23:49:14 IP:211.22.xxx.xxx 未訂閱
不吝嗇的話,可以參考一下小弟的作法~
http://delphi.ktop.com.tw/board.php?cid=30&fid=66&tid=86694
macchen
初階會員


發表:66
回覆:102
積分:33
註冊:2006-07-07

發送簡訊給我
#5 引用回覆 回覆 發表時間:2007-07-27 09:29:54 IP:211.75.xxx.xxx 訂閱
謝謝Stallion您的回覆,想請問一下(不知觀念是否有錯,指教一下),就是你的方式是當第一個client連上要update資料時,用程式將此資料的lock欄位設為1,然後update完後再設為0,可是這種情況下,db不是會將此table做table lock了嗎?如果第二個client也同時在update某筆資料時,此時不是就不能做動作,只能等第一筆做完commit後才能update,想請問一下,如果當資料量很大時,並且相當多的client連線同時要做update的動作時,雖然以我目前的方式可以利用db排隊的機制,可是仍然會有機會產生dead lock的情況(雖然會解鎖,因為還沒到timeout的時間),所以仍想有沒有別的方法可達成相的做法,因為你的作法當然是可行,只是我在想當太多client端在連線(而且db仍有別的程式在跑,我的程式也同時再跑的情況下)是否會常常出現timeout的問題,謝謝。

===================引 用 Stallion 文 章===================
不吝嗇的話,可以參考一下小弟的作法~
http://delphi.ktop.com.tw/board.php?cid=30&fid=66&tid=86694
------
DELPHI初學者
Stallion
版主


發表:52
回覆:1600
積分:1995
註冊:2004-09-15

發送簡訊給我
#6 引用回覆 回覆 發表時間:2007-07-28 15:33:36 IP:211.22.xxx.xxx 未訂閱
1.既然在多人狀態下,當某一Client讀取該RECORD時就要設定,如此別的連線才不會讀到或者有權限寫入該筆資料(當然SQL存取的語法以及留路要自己寫,比較辛苦),當某一Client離開時記得將該欄為RESET為0。我所談的與SQL本身的資料庫鎖定無關,全部由自己寫的程式控制!如果我記得沒錯MSSQL好像只能做到資料集鎖定。
2.多人存取資料庫的作法建議是,當在有必要對資料庫做讀取或寫入時才將連線OPEN!當所有動作(有關寫入動作時不要忘記使用交易)完畢時即刻將連線關閉,因為連線狀態是要花資源的。
===================引 用 macchen 文 章===================
謝謝Stallion您的回覆,想請問一下(不知觀念是否有錯,指教一下),就是你的方式是當第一個client連上要update資料時,用程式將此資料的lock欄位設為1,然後update完後再設為0,可是這種情況下,db不是會將此table做table lock了嗎?如果第二個client也同時在update某筆資料時,此時不是就不能做動作,只能等第一筆做完commit後才能update,想請問一下,如果當資料量很大時,並且相當多的client連線同時要做update的動作時,雖然以我目前的方式可以利用db排隊的機制,可是仍然會有機會產生dead lock的情況(雖然會解鎖,因為還沒到timeout的時間),所以仍想有沒有別的方法可達成相的做法,因為你的作法當然是可行,只是我在想當太多client端在連線(而且db仍有別的程式在跑,我的程式也同時再跑的情況下)是否會常常出現timeout的問題,謝謝。
macchen
初階會員


發表:66
回覆:102
積分:33
註冊:2006-07-07

發送簡訊給我
#7 引用回覆 回覆 發表時間:2007-07-30 09:46:00 IP:211.75.xxx.xxx 訂閱
謝謝你的回覆,大致上的概念我了解了,我會先去試試做做看,如仍有問題再將做法與發生的問題post上來,謝謝各位。

===================引 用 Stallion 文 章===================
1.既然在多人狀態下,當某一Client讀取該RECORD時就要設定,如此別的連線才不會讀到或者有權限寫入該筆資料(當然SQL存取的語法以及留路要自己寫,比較辛苦),當某一Client離開時記得將該欄為RESET為0。我所談的與SQL本身的資料庫鎖定無關,全部由自己寫的程式控制!如果我記得沒錯MSSQL好像只能做到資料集鎖定。
2.多人存取資料庫的作法建議是,當在有必要對資料庫做讀取或寫入時才將連線OPEN!當所有動作(有關寫入動作時不要忘記使用交易)完畢時即刻將連線關閉,因為連線狀態是要花資源的。
------
DELPHI初學者
VICSYS
初階會員


發表:21
回覆:64
積分:32
註冊:2002-10-10

發送簡訊給我
#8 引用回覆 回覆 發表時間:2007-07-30 18:38:37 IP:219.68.xxx.xxx 未訂閱
用 stored procedure 可以這樣寫
try
結果=LockFail
Lock1 timeout 0.0001 sec (NoWait)
Lock2 timeout 0.0001 sec
Lock3 timeout 0.0001 sec
REM 確定上述會異動資源已全部鎖定, 要不然就要 deadlock
結果=UpdateFail
update1
update2
update2
結果=UpdateOk
excetpion (發生失敗的話)
釋放全部交易
回傳
end;

在 delphi 中,
if call_Stored_procedure = LockFail then
begin
Wait....
重試
end
else if call_Stored_procedure = UpdateFail then
showerror
else ...

您只要確定, 在異動前, 所有的資源都已經鎖定, 即可開始異動!

如果要採用 Delphi 來處理會比較複雜.
當執行 Update / Delete 時, DB Server 會 Lock!, 所以不能直接傳送異動的SQL
我解決的方式是 DataSet 進入編輯前, 先傳送 Lock 給 DB Server!
如果 Lock 失敗, 就不要再執行! (不是強制 Lock 要 TimeOut)

Master Detail 的話, 先 Lock Master, 成功後, 再 Lock Detail,
若 Lock Detail 失敗, 要 Release Master!

不過, 一 Lock 就已經啟動交易了. 所以程式離開時, 要 Releae 交易.
另外如果是 MDI 視窗, 要避免同一使用者, 佔用太多資源!
當個一個子視窗進入交易時, 其他視窗視情況禁止進入編輯...

這會不會太複雜了....
系統時間:2024-05-19 2:18:04
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!