線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:4770
推到 Plurk!
推到 Facebook!

請問一下,MS-SQL是否有record lock的設計?

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


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

發送簡訊給我
#1 引用回覆 回覆 發表時間:2009-03-27 09:26:29 IP:219.87.xxx.xxx 訂閱
請問一下,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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2009-04-20 18:03:33 IP:114.46.xxx.xxx 訂閱

===================引 用 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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2009-06-29 13:29:24 IP:219.87.xxx.xxx 訂閱
你好,這個我試過了,在軟體測試時,我一次使用六個軟體在insert資料,然後用enterprise在觀察,仍然會出現dead lock的情況發生,理論上應該是只有會有一個軟體將此標記上到這個table,其它五個就是在等待,直到該標記變false(我用true/false),然後下一個才會又進來,但是測試結果不然,不知還有沒有什麼方法可以解決,謝謝你的回覆。


===================引 用 LPH 文 章===================
你可以在資料表新增一個欄位每次存取時寫入一個LOCK標記存取完成後取消標記讓其他人存取.....
------
DELPHI初學者
LPH
一般會員


發表:53
回覆:43
積分:19
註冊:2003-04-02

發送簡訊給我
#4 引用回覆 回覆 發表時間:2009-06-30 21:17:55 IP:114.46.xxx.xxx 訂閱

===================引 用 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

發送簡訊給我
#5 引用回覆 回覆 發表時間:2009-07-01 08:57:36 IP:75.35.xxx.xxx 未訂閱
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

發送簡訊給我
#6 引用回覆 回覆 發表時間:2009-07-01 09:43:58 IP:219.87.xxx.xxx 訂閱
你好,我測試時是用一台四核電腦跑六個軟體,然後另一台電腦當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

發送簡訊給我
#7 引用回覆 回覆 發表時間:2009-07-01 09:49:24 IP:219.87.xxx.xxx 訂閱
謝謝你的回覆,我有看了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

發送簡訊給我
#8 引用回覆 回覆 發表時間:2009-07-12 13:03:18 IP:124.10.xxx.xxx 訂閱
回錯自刪,抱歉!
------
歡迎參訪 "腦殘賤貓的備忘錄" http://maolaoda.blogspot.com/
編輯記錄
sryang 重新編輯於 2009-07-12 13:05:02, 註解 無‧
Stallion
版主


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

發送簡訊給我
#9 引用回覆 回覆 發表時間:2009-08-05 12:33:09 IP:75.35.xxx.xxx 未訂閱
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

發送簡訊給我
#10 引用回覆 回覆 發表時間:2009-08-05 13:28:33 IP:219.87.xxx.xxx 訂閱
恕刪,非常感謝你的回覆,我有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初學者
系統時間:2024-04-26 9:28:04
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!