电竞比分网-中国电竞赛事及体育赛事平台

分享

delphi 三層 多用戶同時(shí)輸

 獨(dú)孤求財(cái) 2012-03-20

delphi 三層 多用戶同時(shí)輸

時(shí)間:2011-5-26來(lái)源:yang 作者: peng點(diǎn)擊: 25次

我曾經(jīng)問(wèn)過(guò)一次,但卻覺(jué)得答案不太理想,所以重新拋磚引玉。
我的客戶端Delphi錄入、查詢都是用SQL語(yǔ)句,幾乎都是一個(gè)格式,
無(wú)論增加刪除修改我都是只用Tquery控件,而且?guī)缀跻宦墒沁@樣在
按鈕中寫(xiě)的:
Query1.close;
query1.sql.text:=‘insert into table1(...) values(...)‘;
query1.execsql;(or open)
只是在text更換不同的語(yǔ)句?!畇elect * from ...‘,‘delete ...‘
‘update ...‘
有時(shí)候我用兩臺(tái)機(jī)器特意試的時(shí)候,還沒(méi)什么事,但我們公司長(zhǎng)期運(yùn)行
著我的類似程序,有時(shí)卻會(huì)一臺(tái)機(jī)器毫無(wú)反應(yīng),有時(shí)必須其它機(jī)器必須退
出,毫無(wú)反應(yīng)的那臺(tái)機(jī)器起它程序還沒(méi)事,一回Delphi界面什么也做不了。

我想問(wèn)問(wèn)各位你們?cè)诙嗯_(tái)機(jī)器同時(shí)向SQL server錄入的時(shí)候一般的詳細(xì)
編程語(yǔ)句,不出問(wèn)題的編程過(guò)程。

 


來(lái)自:delphi fan2, 時(shí)間:1999-1-25 9:31:00, ID:99075
如果數(shù)據(jù)批量輸入,加入事務(wù)處理!要是全部是Insert是否有你說(shuō)的問(wèn)題?  


來(lái)自:dsp, 時(shí)間:1999-1-25 19:13:00, ID:99113
您用到了事務(wù)嗎?
如果沒(méi)有,不會(huì)出現(xiàn)您的問(wèn)題.
如果用到了,則極有可能是您的兩個(gè)程序出現(xiàn)了死鎖.
因?yàn)?在一個(gè)事物內(nèi)UpDate,Insert,Delete會(huì)隱式加鎖,直到事務(wù)結(jié)束.
如果您的一個(gè)程序?yàn)?

StartTransaction;
query1.close;
query1.clear;
query1.sql.add(‘Insert table1....‘);
query1.execsql;
query1.close;
query1.clear;
query1.sql.add(‘Update table2...‘);
query1.execsql;
query1.Close;
commit;

另一個(gè)為:
StartTransaction;
query2.close;
query2.clear;
query2.sql.add(‘Insert table2....‘);
query2.execsql;
query2.close;
query2.clear;
query2.sql.add(‘Update table1...‘);
query2.execsql;
query2.Close;
commit;

當(dāng)?shù)谝粋€(gè)執(zhí)行到語(yǔ)句Update table2,
而第二個(gè)執(zhí)行到語(yǔ)句Update table1時(shí),
會(huì)出現(xiàn)相互等待的現(xiàn)象.

解決的辦法就是將可能出現(xiàn)沖突的語(yǔ)句全放到事務(wù)中執(zhí)行,而無(wú)論哪一個(gè)
此類事務(wù)均在開(kāi)始處,對(duì)同一個(gè)表加鎖.這樣在事務(wù)開(kāi)始便進(jìn)行了排隊(duì),
直到一個(gè)事務(wù)結(jié)束,另一個(gè)才會(huì)開(kāi)始,便不會(huì)死鎖.
如:
StartTransaction;
query1.close;
query1.clear;
query1.sql.add(‘Select * from commonTable HOLDLOCK‘);
                //對(duì)SQL Server,不同的database server不同.
query1.Open;
query1.close;
query1.clear;
query1.sql.add(‘Insert table1....‘);
query1.execsql;
query1.close;
query1.clear;
query1.sql.add(‘Update table2...‘);
query1.execsql;
query1.Close;
commit;

StartTransaction;
query2.close;
query2.clear;
query2.sql.add(‘Select * from commonTable HOLDLOCK‘);
query2.Open;
query2.close;
query2.clear;
query2.sql.add(‘Insert table2....‘);
query2.execsql;
query2.close;
query2.clear;
query2.sql.add(‘Update table1...‘);
query2.execsql;
query2.Close;
commit;

這樣,二者在select上便進(jìn)行排隊(duì),便解決了排序.

如您根本就沒(méi)有組織過(guò)事務(wù),出現(xiàn)該現(xiàn)象就有點(diǎn)怪了.
 


來(lái)自:希臣, 時(shí)間:1999-1-26 8:27:00, ID:99152
dsp,你說(shuō)的我有點(diǎn)迷糊了。
到底用不用事務(wù)?我一點(diǎn)都沒(méi)有過(guò)事務(wù),
按你說(shuō)的,不用事務(wù),好象是不應(yīng)該出現(xiàn)問(wèn)題--是這個(gè)意思嗎?

Delphi fan2,我的語(yǔ)句Insert,delete ,update,select都有。

兩位,如果其它機(jī)器只用Select,而一臺(tái)機(jī)器(名A)上
Insert,delete,update,select都用,這機(jī)器A會(huì)不會(huì)和其它機(jī)器互鎖

 


來(lái)自:dubhe, 時(shí)間:1999-1-26 9:29:00, ID:99154
dsp:
insert和update時(shí)數(shù)據(jù)庫(kù)只對(duì)當(dāng)前操作的記錄加鎖,而不是對(duì)整個(gè)表加鎖.因此,你
所舉的死鎖例子不會(huì)出現(xiàn)死鎖現(xiàn)象.
希臣:
其它機(jī)器Select,而A機(jī)器Insert,delete,Update,Select都用時(shí),機(jī)器A更不會(huì)與其
它機(jī)器互鎖.

一個(gè)死鎖的例子:
進(jìn)程A   (修改記錄1)------->(修改記錄2)
進(jìn)程B   (修改記錄2)------->(修改記錄1)
另外,建議希臣TQuery的寫(xiě)法:
Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Add:=‘Select ... From table1 Where ...‘;
Query1.Open;
... ...
Query1.Close;//不需要時(shí)馬上Close掉  


來(lái)自:delphi fan2, 時(shí)間:1999-1-26 10:04:00, ID:99156
其實(shí)數(shù)據(jù)庫(kù)都有事務(wù)處理,無(wú)論你使不使,數(shù)據(jù)庫(kù)自己會(huì)使用,所以
你大量輸入數(shù)據(jù)時(shí)要顯式使用可以提高效率和避免死鎖,當(dāng)一個(gè)用戶插入,
而另一個(gè)用戶select是容易出問(wèn)題,在數(shù)據(jù)庫(kù)理論上用事務(wù)的處理級(jí)別來(lái)避免!
不過(guò)Sybase支持幾個(gè)我不知道,在數(shù)據(jù)庫(kù)產(chǎn)品里oracle是支持最好的!其他
產(chǎn)品都無(wú)法使事務(wù)完全獨(dú)立!  


來(lái)自:yaojiaqing, 時(shí)間:1999-1-27 0:05:00, ID:99179
您看這樣行嗎?
1,客戶段絕對(duì)不使用數(shù)據(jù)感知控件,在客戶端錄入完成后,使用一個(gè)
事物處理將數(shù)據(jù)傳之服務(wù)器端。
2,如果客戶端使用數(shù)據(jù)感知控件,在本地用臨時(shí)表,完成錄入后,
在將數(shù)據(jù)上傳,
以上兩種方法,都會(huì)縮短傳輸時(shí)間。這樣網(wǎng)絡(luò)沖突會(huì)很少。
3,對(duì)于多表更新或修改,多用觸發(fā)器或存儲(chǔ)過(guò)程。

 


來(lái)自:delphi fan2, 時(shí)間:1999-1-27 0:13:00, ID:99180
我做數(shù)據(jù)庫(kù)程序時(shí)從不用數(shù)據(jù)感知控件,而且輸入后不要馬上refresh,
因?yàn)閞efresh是很費(fèi)時(shí)的,可以讓用戶手動(dòng)刷新!效果不錯(cuò)!  


來(lái)自:yaojiaqing, 時(shí)間:1999-1-27 0:18:00, ID:99181
再補(bǔ)充兩點(diǎn):
1,事物處理要用,數(shù)據(jù)的完整性嘛。
2,前端的錄入界面中,在錄入時(shí)保證不占用網(wǎng)絡(luò)。(所以說(shuō):要用非數(shù)據(jù)
感知控件)  


來(lái)自:xyw, 時(shí)間:1999-1-27 20:11:00, ID:99217
一定要采用事務(wù)處理;
對(duì)服務(wù)器端要妥善管理;
 


來(lái)自:蓉兒, 時(shí)間:1999-2-3 21:42:00, ID:99874
你的select語(yǔ)句打開(kāi)后什么時(shí)候關(guān)閉的?
其實(shí)很多時(shí)候鎖的造成是由于select而不是insert或update,控制好你取數(shù)據(jù)的機(jī)制就可避免很多鎖,這點(diǎn)我是有成功的經(jīng)驗(yàn).
  Delphi的取數(shù)據(jù)機(jī)制是select結(jié)果集如果未載入完畢(這種情況很多,如DBGrid一次載入只能1000筆,除非你走動(dòng)當(dāng)前記錄,它才會(huì)繼續(xù)載入又一部分),則會(huì)在后臺(tái)數(shù)據(jù)庫(kù)加一個(gè)共享鎖,SQLServer蠢在如果這個(gè)共享鎖有就不能update或insert相應(yīng)頁(yè)面數(shù)據(jù)(該共享鎖鎖的是未載數(shù)據(jù)頁(yè)面),感覺(jué)這種低級(jí)問(wèn)題應(yīng)該不會(huì)有但是確實(shí)存在.
我的實(shí)踐證明MSSQLServer不是一個(gè)很穩(wěn)定的數(shù)據(jù)庫(kù),除非你不亂動(dòng),則一般不會(huì)出錯(cuò).或者說(shuō)用Delphi的數(shù)據(jù)庫(kù)控件(或者說(shuō)是BDE)去訪問(wèn)SQLServer不是很精煉.
不過(guò)也不是根本行不通,設(shè)計(jì)合理還是可以的
建議你:
1.Client端select語(yǔ)句盡量精簡(jiǎn)
2.select取完數(shù)據(jù)則關(guān)閉連接
3.數(shù)據(jù)庫(kù)控件特別是DBGrid盡量少用,寧肯自己多花一點(diǎn)時(shí)間寫(xiě)界面,其實(shí)自己控制一切速度絕對(duì)比它們快得多
4.insert.update語(yǔ)句設(shè)計(jì)合理,能用Trigger盡量用Trigger  


來(lái)自:lzl, 時(shí)間:1999-2-3 23:41:00, ID:99894
前面各位說(shuō)的都很對(duì), 不過(guò)有時(shí)是無(wú)法避免這類問(wèn)題的, 原因出在數(shù)據(jù)庫(kù)
的頁(yè)級(jí)鎖和表級(jí)鎖, 例如在SQL Server 6.5:

1.
begin transaction
insert into delegateinfdetail
values (54,‘23‘,‘43‘,‘1‘,‘1‘,132.00)
waitfor delay "00:00:10"
commit

2. select * from delegateinfdetail

同時(shí)開(kāi)兩個(gè)用戶窗口分別同時(shí)執(zhí)行這兩段SQL, 2會(huì)等待直至1完成事務(wù)提交
可能這是sql server的問(wèn)題, 不知道其它怎么樣.

所以
1. 盡量避免使用數(shù)據(jù)感知控件
2. 減少事務(wù)處理時(shí)間
3. 盡可能使用多線程處理查詢, 避免用戶端等待 (關(guān)于多線程查詢應(yīng)該有例子, 不然
mail 我)
 


來(lái)自:taik, 時(shí)間:1999-2-4 20:18:00, ID:99951
1.先吃個(gè)Sybase補(bǔ)丁,EBFxxxx.exe等,Sybase主頁(yè)上有,很難找。
2.BDE設(shè)置CS Cursors Rows=100~200(BDE 5.01才有)。
3.你Sybase版本?
4.如果不會(huì)多人同時(shí)輸入同一條記錄的話有其他辦法。
5.上面有些提法不對(duì),Sybase最新的版本才有Row級(jí)鎖,舊的
  是Page鎖。
6.要用顯式的事務(wù)控制,在提交出錯(cuò)時(shí)要再嘗試或Rollback.
7.開(kāi)發(fā)環(huán)境接近,好好切磋下。
 


來(lái)自:xhm, 時(shí)間:1999-2-12 7:18:00, ID:100882
沒(méi)有提交,引起死鎖!  


來(lái)自:唐曉鋒, 時(shí)間:1999-2-26 18:14:00, ID:101305
你用線程不行嗎?  


來(lái)自:mindong, 時(shí)間:1999-3-31 1:46:00, ID:103523
線程可以解決。  


來(lái)自:tangyin, 時(shí)間:1999-4-9 22:40:00, ID:104834
我最近也碰到類似的問(wèn)題。在Delphi客戶端用query來(lái)SELECT一個(gè)表,居然導(dǎo)致
其他用戶insert,update等出現(xiàn)阻塞。但不用數(shù)據(jù)感知控件似乎不太現(xiàn)實(shí)。如果
是蓉兒所說(shuō)的情況,希望能有較完善的解決方案。
一是SQL server端能否做些設(shè)置,或Delphi端有什么辦法釋放鎖。  


來(lái)自:silly, 時(shí)間:1999-4-19 19:51:00, ID:105847
Delphi連接SYSBASE11時(shí),BDE的配置使用DB-LIBERARY就不會(huì)造成死瑣,特別針對(duì)SELECT死鎖現(xiàn)象。  


來(lái)自:tai, 時(shí)間:1999-4-20 12:02:00, ID:105872
DB-Liberary是被淘汰的,不建議用,為了兼容才留了這東東。  


來(lái)自:tangyin, 時(shí)間:1999-4-20 12:35:00, ID:105874
不用DB-Liberary你說(shuō)用什么呢?
 


來(lái)自:xhm, 時(shí)間:1999-4-20 12:54:00, ID:105877
CT-Library  


來(lái)自:tangyin, 時(shí)間:1999-4-20 17:50:00, ID:105922
如何配置CT-LIBRARY?  


來(lái)自:silly, 時(shí)間:1999-4-22 23:20:00, ID:106317
WhyNotDBLibrary?TechnicalReasonsPls.  


來(lái)自:SeaSky, 時(shí)間:1999-4-23 0:07:00, ID:106321
你試試 在Select 語(yǔ)句中加上 NoHoldLock選項(xiàng), 例如
  select *  from Tabl1 A NoHoldLock
    where .....


 


來(lái)自:jun_yan, 時(shí)間:1999-4-23 11:21:00, ID:106350
1。TQuery我用的不多,但在使用 TTable 控件時(shí),常常遇到類似的死鎖現(xiàn)象:

  Can‘t perform this on table ,for record has been modified by

other users!

即使用DATA EXPLORER<

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多