請問一下,MS-SQL是否有record lock的設計? |
答題得分者是:Stallion
|
macchen
初階會員 發表:66 回覆:102 積分:33 註冊:2006-07-07 發送簡訊給我 |
請問一下,ms-sql是不是有支援record lock的等級,因為我的軟體會同時執行(指多個軟體介面),而同時也會對同一個table做bulk insert的動作,但是好像同一時間會有多個session到此table做存取的動作,而相當容易導致dead lock的情況發生,因為在執行bulk insert的動作是寫在stored procedure內,並且有對table內的資料做update的指令,但是不同session不會對同樣的資料做update的動作(指有建立index,所以不同session只會對自已的資料做update的動作),而我也有試過在軟體每一次執行時,都會先去check某一個table是否有別的session在對此table做存取,則會一直等待到此session將flag改變時,才可以讓此session進入,但好像也沒有辦法解決問題(指dead lock),所以目前的做法就是在stored procedure內寫cursor的動作,將要update的records先select出來,再用主鍵的方式去更新,請問這樣的做法算是只針對record lock的等級嗎?可是我看「鎖定/被鎖定」內的該table卻會出現「鎖定類型」仍為table lock,而不是使用record lock的模式,因為我對DB的鎖定類型的內容看的不是相當了解,所以想請問各位,有沒有人可以幫忙解釋一下MS-SQL是否有record lock的模式,或是給予一些建議有關如何設計可以將dead lock的發生機率降低到不發生,謝謝各位看完這段相當長的說明。
開發環境: DELPHI 7 MS SQL 2000
------
DELPHI初學者 編輯記錄
macchen 重新編輯於 2009-03-27 11:04:33, 註解 無‧
|
LPH
一般會員 發表:53 回覆:43 積分:19 註冊:2003-04-02 發送簡訊給我 |
===================引 用 macchen 文 章=================== 請問一下,ms-sql是不是有支援record lock的等級,因為我的軟體會同時執行(指多個軟體介面),而同時也會對同一個table做bulk insert的動作,但是好像同一時間會有多個session到此table做存取的動作,而相當容易導致dead lock的情況發生,因為在執行bulk insert的動作是寫在stored procedure內,並且有對table內的資料做update的指令,但是不同session不會對同樣的資料做update的動作(指有建立index,所以不同session只會對自已的資料做update的動作),而我也有試過在軟體每一次執行時,都會先去check某一個table是否有別的session在對此table做存取,則會一直等待到此session將flag改變時,才可以讓此session進入,但好像也沒有辦法解決問題(指dead lock),所以目前的做法就是在stored procedure內寫cursor的動作,將要update的records先select出來,再用主鍵的方式去更新,請問這樣的做法算是只針對record lock的等級嗎?可是我看「鎖定/被鎖定」內的該table卻會出現「鎖定類型」仍為table lock,而不是使用record lock的模式,因為我對DB的鎖定類型的內容看的不是相當了解,所以想請問各位,有沒有人可以幫忙解釋一下MS-SQL是否有record lock的模式,或是給予一些建議有關如何設計可以將dead lock的發生機率降低到不發生,謝謝各位看完這段相當長的說明。 開發環境: DELPHI 7 MS SQL 2000 你可以在資料表新增一個欄位每次存取時寫入一個LOCK標記存取完成後取消標記讓其他人存取..... |
macchen
初階會員 發表:66 回覆:102 積分:33 註冊:2006-07-07 發送簡訊給我 |
你好,這個我試過了,在軟體測試時,我一次使用六個軟體在insert資料,然後用enterprise在觀察,仍然會出現dead lock的情況發生,理論上應該是只有會有一個軟體將此標記上到這個table,其它五個就是在等待,直到該標記變false(我用true/false),然後下一個才會又進來,但是測試結果不然,不知還有沒有什麼方法可以解決,謝謝你的回覆。
===================引 用 LPH 文 章=================== 你可以在資料表新增一個欄位每次存取時寫入一個LOCK標記存取完成後取消標記讓其他人存取.....
------
DELPHI初學者 |
LPH
一般會員 發表:53 回覆:43 積分:19 註冊:2003-04-02 發送簡訊給我 |
===================引 用 macchen 文 章=================== 你好,這個我試過了,在軟體測試時,我一次使用六個軟體在insert資料,然後用enterprise在觀察,仍然會出現dead lock的情況發生,理論上應該是只有會有一個軟體將此標記上到這個table,其它五個就是在等待,直到該標記變false(我用true/false),然後下一個才會又進來,但是測試結果不然,不知還有沒有什麼方法可以解決,謝謝你的回覆。 ===================引 用 LPH 文 章=================== 你可以在資料表新增一個欄位每次存取時寫入一個LOCK標記存取完成後取消標記讓其他人存取.... 一次使用六個軟體在insert資料. 是六個不同軟體在不同機器上 還是在同一機器上的六支不同的程式 可以將程式貼上來或mail: sco.lbh@msa.hinet.net |
Stallion
版主 發表:52 回覆:1600 積分:1995 註冊:2004-09-15 發送簡訊給我 |
|
macchen
初階會員 發表:66 回覆:102 積分:33 註冊:2006-07-07 發送簡訊給我 |
你好,我測試時是用一台四核電腦跑六個軟體,然後另一台電腦當server(mssql),但在客戶端時,是六台電腦透過網路連結一台server,不知這樣是否會與現場情況不同,我把storedporcedure貼到這邊來,請各位幫忙看一下是否有問題,謝謝。
[code delphi] CREATE procedure dbo.execBulkInsert ( @path varchar(30),@KIND VARCHAR(10),@PARAM1 VARCHAR(128), @BoardSN varchar(30),@fdate varchar(20), @up varchar(2), @VINT INT OUTPUT) AS BEGIN DECLARE @vTestCount int, @Var1 VARCHAR(30) SET LOCK_TIMEOUT 30000 if @KIND='AddTable' begin IF NOT EXISTS( SELECT NAME FROM SYSOBJECTS WHERE XTYPE='U' AND NAME='BOARD' @path) BEGIN exec('CREATE TABLE [Board' @path '] ( [fdate] [datetime] NOT NULL , [idstation] [varchar] (50) NOT NULL , [imulti] [varchar] (2) NOT NULL , [cmodel] [varchar] (30) NULL , [Status] [varchar] (5) NULL , [boardsn] [varchar] (100) NULL , CONSTRAINT [PK_Board' @path '] PRIMARY KEY CLUSTERED ( [fdate], [idstation], [imulti] ) ON [PRIMARY] ) ON [PRIMARY]') exec('CREATE TABLE [Component' @path '] ( [fdate] [datetime] NOT NULL , [idstation] [varchar] (50) NOT NULL , [imulti] [varchar] (2) NOT NULL , [cmodel] [varchar] (30) NOT NULL , [Boardsn] [varchar] (100) NULL , [step] [int] NOT NULL, [CompName] [varchar] (30) NOT NULL , [Msr_v] [float] NULL , [Unit_m] [varchar] (10) NULL, [Dev] [varchar] (6) NULL , [Status] [char](1) NULL , [CAD] [varchar] (30) NOT NULL , CONSTRAINT [PK_Component' @path '] PRIMARY KEY CLUSTERED ( [fdate], [idstation], [imulti], [CompName], [cmodel], [step] ) ON [PRIMARY] , CONSTRAINT [FK_Component' @path '_Board' @path '] FOREIGN KEY ( [fdate], [idstation], [imulti] ) REFERENCES [Board' @path '] ( [fdate], [idstation], [imulti] ) ON DELETE CASCADE NOT FOR REPLICATION ) ON [PRIMARY]') END ELSE BEGIN SET @VINT=99 END end SET XACT_ABORT ON Declare @v_fdate datetime, @v_ids varchar(30), @v_imulti varchar(2), @v_bktestbyids int, @vv_bks varchar(10) IF @KIND='Insert' BEGIN SET XACT_ABORT ON BEGIN TRAN if @up = '0' begin DECLARE Board_cursor CURSOR FOR Select fdate, idstation, imulti,bktestbyids From boardsfc WITH (NOLOCK) where BoardSN = @BoardSN and idstation = @path and fdate < @fdate OPEN Board_cursor FETCH NEXT FROM Board_cursor INTO @v_fdate, @v_ids, @v_imulti, @v_bktestbyids WHILE @@FETCH_STATUS = 0 BEGIN set @v_bktestbyids = @v_bktestbyids 1 if @v_bktestbyids < 1000 begin set @vv_bks = @v_bktestbyids set @vv_bks = '0' @vv_bks Exec sp_executesql N'Update boardsfc with(rowlock) Set TestByIDs = @vv_bks, BkTestByIDs = @v_bktestbyids Where fdate = @v_fdate and idstation = @v_ids and imulti = @v_imulti' ,N'@vv_bks varchar(30), @v_bktestbyids int, @v_fdate datetime, @v_ids varchar(30), @v_imulti varchar(2)', @vv_bks = @vv_bks, @v_bktestbyids = @v_bktestbyids, @v_fdate = @v_fdate, @v_ids = @v_ids, @v_imulti = @v_imulti end else Exec sp_executesql N'Update boardsfc with(rowlock) Set TestByIDs = @v_BkTestByIDs, BkTestByIDs = @v_bktestbyids Where fdate = @v_fdate and idstation = @v_ids and imulti = @v_imulti' ,N'@v_bktestbyids int, @v_fdate datetime, @v_ids varchar(30), @v_imulti varchar(2)', @v_bktestbyids = @v_bktestbyids, @v_fdate = @v_fdate, @v_ids = @v_ids, @v_imulti = @v_imulti FETCH NEXT FROM Board_cursor INTO @v_fdate, @v_ids, @v_imulti, @v_bktestbyids END CLOSE Board_cursor DEALLOCATE Board_cursor end exec ('bulk insert board' @path ' from ''' @PARAM1 @path 'board.txt'' WITH (BATCHSIZE = 1000, FIELDTERMINATOR = '','', TABLOCK , MAXERRORS=0 )') exec ('bulk insert component' @path ' from ''' @PARAM1 @path 'component.txt'' WITH ( BATCHSIZE = 1000, FIELDTERMINATOR = '','', TABLOCK , MAXERRORS=0 )') exec ('bulk insert boardSFC from ''' @PARAM1 @path 'boardSFC.txt'' WITH (BATCHSIZE = 1000, FIELDTERMINATOR = '','', TABLOCK , MAXERRORS=0 )') exec ('bulk insert componentSFC from ''' @PARAM1 @path 'componentSFC.txt'' WITH ( BATCHSIZE = 1000, FIELDTERMINATOR = '','', TABLOCK , MAXERRORS=0 )') exec ('bulk insert OpenShort from ''' @PARAM1 @path 'Pin.txt'' WITH (BATCHSIZE = 1000, FIELDTERMINATOR = '','', TABLOCK , MAXERRORS=0 )') COMMIT TRAN RETURN END IF @KIND='InsertDT' BEGIN SET XACT_ABORT ON BEGIN TRAN if @up = '0' begin DECLARE Board_cursor CURSOR FOR Select fdate, idstation, imulti,bktestbyids From boardsfc WITH (NOLOCK) where BoardSN = @BoardSN and idstation = @path and fdate < @fdate OPEN Board_cursor FETCH NEXT FROM Board_cursor INTO @v_fdate, @v_ids, @v_imulti, @v_bktestbyids WHILE @@FETCH_STATUS = 0 BEGIN set @v_bktestbyids = @v_bktestbyids 1 begin set @vv_bks = @v_bktestbyids set @vv_bks = '0' @vv_bks Exec sp_executesql N'Update boardsfc with(rowlock) Set TestByIDs = @vv_bks, BkTestByIDs = @v_bktestbyids Where fdate = @v_fdate and idstation = @v_ids and imulti = @v_imulti' ,N'@vv_bks varchar(30), @v_bktestbyids int, @v_fdate datetime, @v_ids varchar(30), @v_imulti varchar(2)', @vv_bks = @vv_bks, @v_bktestbyids = @v_bktestbyids, @v_fdate = @v_fdate, @v_ids = @v_ids, @v_imulti = @v_imulti end Exec sp_executesql N'Update boardsfc with(rowlock) Set TestByIDs = @v_BkTestByIDs, BkTestByIDs = @v_bktestbyids Where fdate = @v_fdate and idstation = @v_ids and imulti = @v_imulti' ,N'@v_bktestbyids int, @v_fdate datetime, @v_ids varchar(30), @v_imulti varchar(2)', @v_bktestbyids = @v_bktestbyids, @v_fdate = @v_fdate, @v_ids = @v_ids, @v_imulti = @v_imulti FETCH NEXT FROM Board_cursor INTO @v_fdate, @v_ids, @v_imulti, @v_bktestbyids END CLOSE Board_cursor DEALLOCATE Board_cursor end exec ('bulk insert boardSFC from ''' @PARAM1 @path 'boardSFC.txt'' WITH (BATCHSIZE = 1000, FIELDTERMINATOR = '','', TABLOCK , MAXERRORS=0 )') exec ('bulk insert componentSFC from ''' @PARAM1 @path 'componentSFC.txt'' WITH ( BATCHSIZE = 1000, FIELDTERMINATOR = '','', TABLOCK , MAXERRORS=0 )') exec ('bulk insert OpenShort from ''' @PARAM1 @path 'Pin.txt'' WITH (BATCHSIZE = 1000, FIELDTERMINATOR = '','', TABLOCK , MAXERRORS=0 )') COMMIT TRAN RETURN END IF @KIND='InsertSpec' BEGIN SET XACT_ABORT ON BEGIN TRAN exec ('bulk insert ICTSpec from ''' @PARAM1 'ICTSpec.txt'' WITH ( FORMATFILE=''' @PARAM1 'ICTSpec.fmt'', TABLOCK , MAXERRORS=0 )') COMMIT TRAN RETURN END END GO [/code] ===================引 用 LPH 文 章=================== 恕刪 你可以在資料表新增一個欄位每次存取時寫入一個LOCK標記存取完成後取消標記讓其他人存取.... 一次使用六個軟體在insert資料. 是六個不同軟體在不同機器上 還是在同一機器上的六支不同的程式 可以將程式貼上來或mail: sco.lbh@msa.hinet.net
------
DELPHI初學者 |
macchen
初階會員 發表:66 回覆:102 積分:33 註冊:2006-07-07 發送簡訊給我 |
謝謝你的回覆,我有看了Mr. aftcast回覆的文章,想不到提問題的人也與我一樣使用一個table去做確認是否有client在使用mssql的方式,但依照Mr. aftcast大的說法,應該是不需要才對,而我在上面回覆的sp(指預儲程序),我有將begintran寫在sp中(Mr. aftcast大好像也是這樣建議),只是我沒有設定過IsolationLevel這個條件,如果像Mr. aftcast大的說法,因為我在sp內寫for的原因是因為想說是不是因為update時,會造成table lock,所以我使用index的方式,看是否可以讓該table降為row lock的等級,所以才會這樣子寫,不知這方面的觀念是否正確,麻煩Stallion再指教一下,謝謝。
===================引 用 Stallion 文 章=================== hello Machen, please check out below link http://delphi.ktop.com.tw/board.php?cid=30&fid=66&tid=96041 Mr. aftcast is experienced on database locking issue.
------
DELPHI初學者
編輯記錄
macchen 重新編輯於 2009-07-01 10:37:41, 註解 在此備註一下,我的軟體是會一直塞資料,幾本上是沒有停止的在塞,就是一直會連個db,謝謝。‧
|
sryang
尊榮會員 發表:39 回覆:762 積分:920 註冊:2002-06-27 發送簡訊給我 |
|
Stallion
版主 發表:52 回覆:1600 積分:1995 註冊:2004-09-15 發送簡訊給我 |
Hello macchen,
I am sorry for late response, actually I can't answer your question dueto my limited knowledge on database programming, but try to send a message to Mr. aftcast to see if you can get any response from him. ===================引 用 macchen 文 章=================== 謝謝你的回覆,我有看了Mr. aftcast回覆的文章,想不到提問題的人也與我一樣使用一個table去做確認是否有client在使用mssql的方式,但依照Mr. aftcast大的說法,應該是不需要才對,而我在上面回覆的sp(指預儲程序),我有將begintran寫在sp中(Mr. aftcast大好像也是這樣建議),只是我沒有設定過IsolationLevel這個條件,如果像Mr. aftcast大的說法,因為我在sp內寫for的原因是因為想說是不是因為update時,會造成table lock,所以我使用index的方式,看是否可以讓該table降為row lock的等級,所以才會這樣子寫,不知這方面的觀念是否正確,麻煩Stallion再指教一下,謝謝。 ===================引 用 Stallion 文 章=================== hello Machen, please check out below link http://delphi.ktop.com.tw/board.php?cid=30&fid=66&tid=96041 Mr. aftcast is experienced on database locking issue. |
macchen
初階會員 發表:66 回覆:102 積分:33 註冊:2006-07-07 發送簡訊給我 |
恕刪,非常感謝你的回覆,我有pm給aftcast並且有到他的blog上麻煩他可以幫忙解一下這個問題了,但好像沒得到回覆,而且連pm都沒回了,不知是太忙了,還是沒去看pm,我知道他對db好像很有經驗,但我沒有別的方法可以請教他,所以只能等到的回覆,但還是很謝謝stallion大大你的指導,謝謝。
===================引 用 Stallion 文 章=================== Hello macchen, I am sorry for late response, actually I can't answer your question dueto my limited knowledge on database programming, but try to send a message to Mr. aftcast to see if you can get any response from him.
------
DELPHI初學者 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |