經過在數據庫中加入version 字段,解決併發時 進行「回顯修改」 操做時,sql
對不一樣用戶對同一數據進行同時修改時,後面的修改會覆蓋前面的修改的問題。數據庫
出現問題的狀況描述和問題解決概述:session
這個截圖的源文件連接:有道雲筆記mybatis
一、已經添加事務了,爲何不能解決,還要加這個version 字段?併發
事務對併發的解決主要在,事務的隔離級別(未提交讀,提交讀,可重複讀,序列化)。他解決的是一個事務執行時的併發問題。但回顯修改不在一個事務中。app
二、這樣徹底解決了嗎?工具
並無,這裏加入version 字段解決的只是回顯到表單,到提交後執行到 if(newVersion == oldversion) 的問題。 當兩個操做,都進入到if(newVersion == oldversion) { } 代碼塊裏。提交有前後就又出現問題了。spa
但咱們知道併發中出現的問題機率,是和執行一個操做的時間有關的,在這個問題裏,「用戶查看錶單,再點擊修改的時間」,和」程序進入這個if代碼塊內後程序的執行時間」明顯站據了大頭(90%)。code
也就是說加入version 解決了咱們的大問題。xml
三、怎樣徹底解決?
很簡單,在使用version 的基礎上給 這段修改代碼方法加鎖。保證同一時間只有一我的能提交修改,這就解決了剩下那段的問題。
四、有沒有其餘的方法?
有!(下面的示例代碼有侷限性)
就是你提交更新的時候,僅更新你修改了的項。這樣的話就不會覆蓋別人的東西了。
1)把原來的回顯的時候的對象放入session 中。
2)把修改提交後獲得新對象,和放在session 中的老對象,傳入service
3)在service層中進行對比,沒有改過的項置爲null ,改過的保留改後的。
比較不一樣的工具代碼
四、在mapper層中經過動態sql(mybatis) ,按需更新。
<update id="updateTargetPhone" parameterType="TargetPhone"> UPDATE tb_target_phone <set> <if test="phone.name != null"> name = #{phone.name}, </if> <if test="phone.remainMoney != null"> remain_money = #{phone.remainMoney}, </if> <if test="phone.smsSend != null"> sms_send = #{phone.smsSend} </if> </set> WHERE id = #{phone.id} </update>