首先使用下面的sql語句查詢資料庫的產品表:
select*from
products
where
categoryid=1
查詢結果如下圖:
為了看起來清晰,我已經事先把所有分類為1產品的**和庫存修改為相同值了。然後執行下面的程式:
varquery
=from
p in
ctx.products
where
p.categoryid ==1
select
p;foreach (
varp
inquery)
p.unitsinstock
=convert
.toint16(p.unitsinstock -1
);ctx.submitchanges();
//在這裡設斷點
我們使用除錯方式啟動,由於設定了斷點,程式並沒有進行更新操作。此時,我們在資料庫中執行下面的語句:
updateproducts
setunitsinstock
=unitsinstock -2
, unitprice
=unitprice +1
where
categoryid =1
然後在繼續程式,會得到修改併發(樂觀併發衝突)的異常,提示要修改的行不存在或者已經被改動。當客戶端提交的修改物件自讀取之後已經在資料庫中發生改 動,就產生了修改併發。解決併發的包括兩步,一是查明哪些物件發生併發,二是解決併發。如果你僅僅是希望更新時不考慮併發的話可以關閉相關列的更新驗證, 這樣在這些列上發生併發就不會出現異常:
[column(storage="_unitsinstock", dbtype="smallint", updatecheck = updatecheck.never)][
column(storage="_unitprice", dbtype="money", updatecheck = updatecheck.never)
]
為這兩列標註不需要進行更新檢測。假設現在產品**和庫存分別是27和32。那麼,我們啟動程式(設定端點),然後執行update語句,把**+1,庫 存-2,然後**和庫存分別為28和30了,繼續程式可以發現**和庫存分別是28和 31。**+1是之前更新的功勞,庫存最終是-1是我們程式之後更新的功勞。當在同乙個欄位上(庫存)發生併發衝突的時候,預設是最後的那次更新獲勝。
解決併發
如果你希望自己處理併發的話可以把前面對列的定義修改先改回來,看下面的例子:
var query=from p
inctx.products where p.categoryid ==1
select p;
foreach
(var p
inquery)
p.unitsinstock
=convert.toint16(p.unitsinstock -1
);try
catch
(changeconflictexception)
}ctx.submitchanges();
LinQ to SQL 併發與事務 3
最後,我們把提交語句修改為 ctx.submitchanges conflictmode.failonfirstconflict 表示第一次發生衝突的時候就不再繼續了,然後並且去除最後的ctx.submitchanges 語句。來測試一下,在執行了sql後再繼續程式可以發現介面上只輸出了數字1,說明...
Linq to sql 檢測併發
首先使用下面的 sql 語句查詢資料庫的產品表 select from products where categoryid 1 為了看起來清晰,我已經事先把所有分類為 1 產品的 和庫存修改為相同值了。然 後執行下面的程式 varquery from p in ctx.products where ...
LINQ TO SQL 併發控制
column特性的updatacheck用於設定併發衝突處理方式 always 使用使用這個列進行衝突檢測 never 從不使用這個列進行衝突檢測 whenchanged 僅在成員被應用程式更改時使用這個列檢測 這裡的檢測指傳送的sql中的where中的條件,如userinfo表中name列進行衝突...