mysql 插入返回主鍵 併發問題

現象:
    當業務涉及主從訂單表時,主表主鍵OrderID爲自增列,這時在涉及添加操作時,往往會出現如下的編程思路
    insert order(...) values(...)
    select @@identity
    程序中再接收返回的值,作爲OrderDetail表中OrderID的值,做Insert操作

問題:
    單用戶沒有問題,小併發量可能沒有問題
    大併發量時,就會發現一個訂單的明細,出現在另一個訂單的明細中

    這個問題我遇到過,新同事們也遇到過,因此,感覺是一個普遍的問題,其實問題很簡單,問題涉及的知識點就是SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY的區別 
    
    [引用Lich King]
    IDENT_CURRENT 返回爲任何會話和任何作用域中的特定表最後生成的標識值。 
    @@IDENTITY 返回爲當前會話的所有作用域中的任何表最後生成的標識值。 
    SCOPE_IDENTITY 返回爲當前會話和當前作用域中的任何表最後生成的標識值。

    例如,有兩個表 T1 和 T2,在 T1 上定義了一個 INSERT 觸發器。當將某行插入 T1 時,觸發器被激發,並在 T2 中插入一行。此例說明了兩個作用域:一個是在 T1 上的插入,另一個是作爲觸發器的結果在 T2 上的插入。
  假設 T1 和 T2 都有 IDENTITY 列,@@IDENTITY 和 SCOPE_IDENTITY 將在 T1 上的 INSERT 語句的最後返回不同的值。
  @@IDENTITY 返回插入到當前會話中任何作用域內的最後一個 IDENTITY 列值,該值是插入 T2 中的值。
  SCOPE_IDENTITY() 返回插入 T1 中的 IDENTITY 值,該值是發生在相同作用域中的最後一個 INSERT。如果在作用域中發生插入語句到標識列之前喚醒調用 SCOPE_IDENTITY() 函數,則該函數將返回 NULL 值。
  而IDENT_CURRENT('T1') 和 IDENT_CURRENT('T2') 返回的值分別是這兩個表最後自增的值。

    
    因此,對於@@IDENTITY要儘量避免使用,因爲在大型開發中,你根本無法知道你獲得的是哪個自增列值,而儘量採用 SCOPE_IDENTITY() 函數,SCOPE_IDENTITY() 是在一個操作範圍之內,最後一步操作所產生的自增列的值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章