原创

MySQL-使用联合唯一索引和 ON DUPLICATE KEY UPDATE控制重复插入不产生新数据-高并发死锁及其解决方案

<insert id="insertIntentService" parameterType="com.f6car.maintain.po.maintain.TsMaintainIntentService">
insert into ts_maintain_intent_service (id_group,id_car,creation_date,maintain_suggestion)
values (#{idGroup},#{idCar},now(),#{maintainSuggestion})
ON DUPLICATE KEY UPDATE
<if test="maintainSuggestion !=null">
`maintain_suggestion` = #{maintainSuggestion},
</if>
`modifiedtime` = now()
</insert>

跟ON DUPLICATE KEY UPDATE相似的应该还有replace into(如果存在就update,如果不存在就插),未测试!!!
注意:容易在高并发的情况下发生死锁
解决方案:
1. 先select 判断再insert or update
2. 在insert语句上try catch,最好只捕获 DUPLICATE Key 相关的DuplicateKeyException异常,在此异常中执行update,其他异常直接抛出,
扩展:
如果在某些场景下,需要批量导入数据,这个时候如果出现DuplicateKeyException,可以使用IGNORE,忽略错误,继续导入。
IGNORE关键字
MySQL INSERT IGNORE语句简介当使用INSERT语句向表中添加一些行数据并且在处理期间发生错误时,INSERT语句将被中止,并返回错误消息。因此,可能不会向表中没有插入任何行。但是,如果使用INSERT INGORE语句,则会忽略导致错误的行,并将其余行插入到表中。INSERT INGORE语句的语法如下:INSERT IGNORE INTO table(column_list)
VALUES( value_list),
( value_list),
...
SQL请注意,IGNORE子句是MySQL对SQL标准的扩展。


正文到此结束
本文目录