经过在数据库中加入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>