none
[VB2005] 並行違規的問題 RRS feed

  • 問題

  • 開發環境:Visual Basic 2005
    資料庫:SQL Server 2005

    現在遇到一個問題,我用DataAdapter Fill資料到DataTable中
    然後DataTable改動後透過CommandBuilder產生UpdateCommand,然後Update 回資料庫

    然後現在發生一個問題,當有兩個人同時編輯一筆資料的時候,而先後按下儲存按鈕
    後來的人會產生一個錯誤:

    資料回存錯誤:
    並行違規:UpdateCommand已經影響必須是1記錄的0

    為什麼會這樣啊?如果我想要讓後一個人的資料取代掉先前的人修改後存的資料
    要怎麼做才行啊?

    謝謝了!

     

    2006年10月16日 上午 07:27

解答

  • 這就是 CommandBuilder 會產生的 SQL 指令,這是以資料內容為基礎確定該資料列就是要更新的那一列,不論你有沒有設主索引 .
    如果看不慣,請自己寫,而且我本來就建議少用 CommandBuilder,最好是都不要用,除非你真的夠了解它(其實愈了解,你會愈不想用它)

    2006年10月16日 上午 08:39
    版主

所有回覆

  • 我將DataAdapter.ContinueUpdateOnError 設定成True後
    並不會產生錯誤,但是也不會更動到

    現在好像有找到問題所在,他CommandBuilder中的UpdateCommand為:

    UPDATE [company] SET [cocode] = @p1, [cospcode] = @p2, [cosname] = @p3, [cofname] = @p4, [coperchar] = @p5, [couniform] = @p6, [cotel] = @p7, [cocell] = @p8, [cofax] = @p9, [cozip] = @p10, [coadd] = @p11, [cotax] = @p12, [cogroup] = @p13, [coadddate] = @p14 WHERE (([cocode] = @p15) AND ([cospcode] = @p16) AND ([cosname] = @p17) AND ([cofname] = @p18) AND ((@p19 = 1 AND [coperchar] IS NULL) OR ([coperchar] = @p20)) AND ((@p21 = 1 AND [couniform] IS NULL) OR ([couniform] = @p22)) AND ((@p23 = 1 AND [cotel] IS NULL) OR ([cotel] = @p24)) AND ((@p25 = 1 AND [cocell] IS NULL) OR ([cocell] = @p26)) AND ((@p27 = 1 AND [cofax] IS NULL) OR ([cofax] = @p28)) AND ((@p29 = 1 AND [cozip] IS NULL) OR ([cozip] = @p30)) AND ((@p31 = 1 AND [coadd] IS NULL) OR ([coadd] = @p32)) AND ((@p33 = 1 AND [cotax] IS NULL) OR ([cotax] = @p34)) AND ((@p35 = 1 AND [cogroup] IS NULL) OR ([cogroup] = @p36)) AND ([coadddate] = @p37))

    為何他Where後面掛一大串?

    有沒有辦法讓他掛少一點啊?就只掛Where ([cocode] = @p15)就好了

    因為cocode是主索引,不會重複也不會是空的....

    CommandBuilder一定要這樣嗎?

    2006年10月16日 上午 08:00
  • 沒錯...CommandBuilde產生的Commandtext就是這樣
    2006年10月16日 上午 08:15
  • 這就是 CommandBuilder 會產生的 SQL 指令,這是以資料內容為基礎確定該資料列就是要更新的那一列,不論你有沒有設主索引 .
    如果看不慣,請自己寫,而且我本來就建議少用 CommandBuilder,最好是都不要用,除非你真的夠了解它(其實愈了解,你會愈不想用它)

    2006年10月16日 上午 08:39
    版主
  •  小朱 寫信:

    這就是 CommandBuilder 會產生的 SQL 指令,這是以資料內容為基礎確定該資料列就是要更新的那一列,不論你有沒有設主索引 .
    如果看不慣,請自己寫,而且我本來就建議少用 CommandBuilder,最好是都不要用,除非你真的夠了解它(其實愈了解,你會愈不想用它)

    :::假如不用CommandBuilder的話,若有十幾個資料表有可能需要

    做修改時,且每個資料表的欄位名稱,型態又不同,請問大大對於這

    種並行違規的情況該怎麼解決???

     

    2006年10月16日 下午 01:15
  • 可以的話,儘量縮短鎖定的時間,例如只有在執行更新資料時才鎖定,也就是只在更新指令下達前才下 BeginTransaction 指令 .
    2006年10月16日 下午 02:24
    版主
  • :::但是用交易的方式能夠解決並行違規的情況嗎???

    因為用交易的方式主要是用來防止資料不一致的情況不是嗎???.....@@?

    小朱大大能否詳細說明一下.........

    2006年10月17日 上午 03:09
  • 呃 ... 因為發生資料鎖定問題最多的狀況都是在 Transaction 進行時 .
    其實不管是否為交易,都要儘量縮短資料列被鎖定的時間 .

    通常在進行交易時,會增加資料列被鎖定的時間,才會有 Isolation Level (隔離層次) 的機制 .
    如果有要進行交易且預期會有許多並行的連線時,就需要使用到 Isolation Level.
    仍然要盡可能的縮短交易時間,因為在交易期間資料列都會被鎖定 .

    2006年10月17日 上午 03:27
    版主