2014-03-25 47 views
0

這裏最大的標識ID是代碼:檢索使用的TransactionScope

using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew)) 
{ 
    DBContext.AddtoSomeTable(record); 
    System.Threading.Thread.Sleep(5000); 
    DBContext.SaveChanges(); 

    MAX_ID = (from t in DBContext.SomeTable 
       select t.ID).Max(); 

    scope.Complete(); 
} 

據我所知,完成範圍前,MAX_ID應該是新記錄的ID,這是剛剛插入。即使有兩個用戶同時提交,後面的用戶也應該等到第一個用戶的TransactionScope完成。

但是,會發生什麼是兩個用戶得到相同的MAX_ID。這意味着在將第一人的記錄插入數據庫之後,插入第二人的記錄,然後第一個人獲得他的MAX_ID

我認爲在一個事務中,表被鎖定以避免髒數據。任何人都可以解釋嗎?

編輯: ID字段是自動遞增

+0

我認爲框架是假設返回新插入的對象的ID。你是否看過記錄中返回的內容? ID字段? –

+0

@lrb id是自動遞增的,所以記錄沒有那個字段,那是什麼意思? – pita

+1

我在猜測插入的業務對象有一個自動遞增的主鍵字段,如果配置正確,BO的ID字段在SaveChanges後將有一個更新的ID。 –

回答

1

不同類型和範圍的鎖的操作和鎖定範圍時採取將改變由於鎖升級爲鎖的數量增加。如果在單個事務中,您要在單個表中插入/更新/刪除單個行,則最有可能會採用獨佔行鎖。當你在該表中更新/插入/刪除更多行時,一旦你累積了一定數量的行鎖,鎖升級會將它們提升爲頁鎖。積累充足的頁面鎖,你將升級到表鎖。

我不知道你想用select max(id) from someTable來做什麼,但是如果你期望它能夠反映你的SaveChanges()的操作,最有可能的是,你正在創建一個競爭條件。

假設你正在使用SQL Server,內置功能scope_identity()會給你

插入在同一範圍內的標識列的最後一個標識值。 作用域是一個模塊:存儲過程,觸發器,函數或分批「

然而:如果,在相同的範圍內,則,比方說,將行插入兩個不同的表,每一個具有標識列,

begin transaction 
insert foo() ... 
insert bar() ... 
commit transaction 

scope_identity()給你剛纔生成的範圍(該表bar在這個例子中)的最後一個值。

+0

我想獲得記錄的自動遞增的ID,我剛剛插入,並且我正在使用EF,它不能直接調用scope_identity(),我認爲,但是@lrb提到的解決方案其實很簡單,我可以在SaveChange()之後直接調用MAX_ID = record.ID。謝謝大家 – pita