记一次高并发更新 feature–拓展字段 问题
前言:
原思路:
- 从数据库查出原有feature 1
- 更新要修改的内容 2
- 整个feature置入数据库 3
问题:
在高并发情况下:
两线程同时查出了feature,并先后完成了2-3步,
结果:
更新被覆盖
解决办法:
使用数据库JSON操作函数,在数据库上更新。使用数据库默认的更新排它锁。但更新的时候注意集合类的处理
<!-- 更新扩展信息 -->
<sql id="setFeature">
feature = JSON_SET(
IFNULL(feature, '{}'),
<foreach collection="jobFeature" item="featureItem" separator=",">
CONCAT('$.', #{featureItem.key}) ,
<choose>
<when test="featureItem.value instanceof java.util.List">
JSON_ARRAY(
<foreach collection="featureItem.value" item="valueItem" separator=",">
#{valueItem}
</foreach>
)
</when>
<otherwise>
#{featureItem.value}
</otherwise>
</choose>
</foreach>
)
</sql>
feature 结果{"msg": "null", "lights": ["1", "2"], "haveStatus": 1}
<!-- 更新扩展信息 -->
<sql id="setFeature">
feature = JSON_SET(
IFNULL(feature, '{}'),
<foreach collection="jobFeature" item="item" index="index" separator=",">
CONCAT('$.', #{item.key}), #{item.value}
</foreach>
)
</sql>
feature结果:{"msg": "null", "lights": "base64:type15:rO0ABXNyAB5jb20uYWxpYmFiYS5mYXN0anNvbi5KU09OQXJyYXkAAAAAAAAAAQIAAUwABGxpc3R0 ABBMamF2YS91dGlsL0xpc3Q7eHBzcgATamF2YS51dGlsLkFycmF5TGlzdHiB0h2Zx2GdAwABSQAE c2l6ZXhwAAAAAncEAAAAAnQAATF0AAEyeA==", "haveStatus": 1}
证明在直接操作JSON的时候注意List集合类的处理。
总结
在高并发的接口中更新feature一定要注意可能存在的问题,对于前端页面的更新则不必使用SQL的JSON操作,因为前端页面没有高并发的更新。