mysql 插入返回主鍵 併發問題

2021-09-19 03:14:36 字數 1130 閱讀 7551

現象:

當業務涉及主從訂單表時,主表主鍵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() 是在乙個操作範圍之內,最後一步操作所產生的自增列的值。

mysql併發問題調查

在做乙個併發搶購功能,使用併發鎖庫存邏輯後,發現還有漏網之魚導致超賣。調查後,發現庫存資料鎖定成功,但存在幾筆失敗,即扣完庫存後被別的更新覆蓋了,出現該問題主要是設計問題,鎖庫存欄位被多方更新,通過更改,使得庫存更新只能通過專門方法解決該問題。此處主要想記錄解決問題的方法。1 通過日誌調查知道庫存鎖...

mybitas插入返回主鍵

id adduser parametertype bean.user usegeneratedkeys true keyproperty id insert into user name email password values insert usegeneratedkeys 取值範圍true f...

解決併發問題

一.使用redis鎖 智慧型雲 工單系統 搶單 工單id鎖key public static final string cloud live gain order lock orderid cloud live gain order lock orderid component public cla...