on duplicate key update導致主鍵不連續自增解決方案

來源:互聯網
上載者:User

on duplicate key update導致主鍵不連續自增解決方案

最近項目上需要實現這麼一個功能:統計每個人每個軟體的使用時間長度,用戶端發過來訊息,如果該使用者該軟體已經存在增更新使用時間,如果沒有則新添加一條記錄,代碼如下:

    <!-- 批量儲存軟體使用時間長度表 -->
    <update  id="saveApp"  parameterType="java.util.List">
    <foreach collection="appList" item="item" index="index"  separator=";">
     insert into app_table(userName,app,duration)
     values(#{userName},#{item.app},#{item.duration})
     on duplicate key update duration=duration+#{item.duration}
  </foreach>
  </update>

為了效率用到了on duplicate key update進行自動判斷是更新還是新增,一段時間後發現該表的主鍵id(已設定為連續自增),不是連續的自增,總是跳躍的增加,這樣就造成id自增過快,已經快超過最大值了,通過尋找資料發現,on duplicate key update有一個特性就是,每次是更新的情況下id也是會自增加1的,比如說現在id最大值的5,然後進行了一次更新操作,再進行一次插入操作時,id的值就變成了7而不是6.
為瞭解決這個問題,有兩種方式,第一種是修改innodb_autoinc_lock_mode中的模式,第二種是將語句修拆分為更新和操作2個動作

第一種方式:innodb_autoinc_lock_mode中有3中模式,0,1和2,mysql5的預設配置是1,

0是每次分配自增id的時候都會鎖表.

1隻有在bulk insert的時候才會鎖表,簡單insert的時候只會使用一個light-weight mutex,比0的並發效能高

2.沒有仔細看,好像是很多的不保證...不太安全.

資料庫預設是1的情況下,就會發生上面的那種現象,每次使用insert into .. on duplicate key update 的時候都會把簡單自增id增加,不管是發生了insert還是update

由於該代碼資料量大,同時需要更新和添加的資料量多,不能使用將0模式,只能將資料庫代碼拆分成為更新和插入2個步驟,第一步先根據使用者名稱和軟體名更新使用時間長度,代碼如下:

  <update id="updateApp" parameterType="App">
   update app_table
   set duration=duration+#{duration}
   where userName=#{userName} and appName=#{appName}
  </update>

然後根據傳回值,如果傳回值大於0,說明更新成功不再需要插入資料,如果傳回值小於0則需要進行插入該條資料,代碼如下:

<insert id="saveApp" keyProperty = "id" useGeneratedKeys = "true"  parameterType="App">
   insert into app_table(userName,appName,duration)
   values(#{userName},#{appName},#{duration})
  </insert>

這樣解決效率上肯定為受到影響,不知道會不會丟資料,觀察一段時間再最佳化吧!

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.