死锁问题------------------------INSERT ... ON DUPLICATE KEY UPDATE*(转)
前言
我们在实际业务场景中,经常会有一个这样的需求,插入某条记录,如果已经存在了则更新它如果更新日期或者某些列上的累加操作等,我们肯定会想到使用INSERT ... ON DUPLICATE KEY UPDATE语句,一条语句就搞定了查询是否存在和插入或者更新这几个步骤,但是使用这条语句在msyql的innodb5.0以上版本有很多的陷阱,即有可能导致death lock死锁也有可能导致主从模式下的replication产生数据不一致。
正文
正如前言说的那样,在实际业务中,曾经有过一个需求就是插入一条业务数据,如果不存在则新增,存在则累加更新某一个字段的值,于是乎就想到了使用insert... on duplicate key update这个语句,但是有一天去测试环境查看错误日志时,却发现了在多个事务并发执行同一条insert...on duplicate key update 语句时,也就是insert的内容相同时,发生 了死锁。
对于insert...on duplicate key update这个语句会引发dealth lock问题,官方文档也没有相关描述,只是进行如下描述:
An INSERT ... ON DUPLICATE KEY UPDATE statement against a table having more than one unique or primary key is also marked as unsafe. (Bug #11765650, Bug #58637)
也就是如果一个表定义有多个唯一键或者主键时,是不安全的,这又引发了以一个问题,见https://bugs.mysql.com/bug.php?id=58637
也就是
当mysql执行INSERT ON DUPLICATE KEY的 INSERT时,存储引擎会检查插入的行是否会产生重复键错误。如果是的话,它会将现有的
行返回给mysql,mysql会更新它并将其发送回存储引擎。当表具有多个唯一或主键时,此语句对存储引擎检查密钥的顺序非常敏感。根据这个顺序,
存储引擎可以确定不同的行数据给到mysql,因此mysql可以更新不同的行。存储引擎检查key的顺序不是确定性的。例如,InnoDB按照索引添加到
表的顺序检查键。
insert ... on duplicate key 在执行时,innodb引擎会先判断插入的行是否产生重复key错误,如果存在,在对该现有的行加上S(共享锁)锁,如果返回该行数据给mysql,然后mysql执行完duplicate后的update操作,然后对该记录加上X(排他锁),最后进行update写入。
如果有两个事务并发的执行同样的语句,那么就会产生death lock,如:

具体的bug描述见:https://bugs.mysql.com/bug.php?id=52020
https://bugs.mysql.com/bug.php?id=58637
编辑
https://bugs.mysql.com/bug.php?id=21356
解决办法:
1、尽量不对存在多个唯一键的table使用该语句
2、在有可能有并发事务执行的insert 的内容一样情况下不使用该语句
---------------------
作者:个人技术博客-潘民兰
来源:CSDN
原文:https://blog.csdn.net/pml18710973036/article/details/78452688
版权声明:本文为博主原创文章,转载请附上博文链接!
死锁问题------------------------INSERT ... ON DUPLICATE KEY UPDATE*(转)的更多相关文章
- INSERT ... ON DUPLICATE KEY UPDATE产生death lock死锁原理
前言 编辑 我们在实际业务场景中,经常会有一个这样的需求,插入某条记录,如果已经存在了则更新它如果更新日期或者某些列上的累加操作等,我们肯定会想到使用INSERT ... ON DUPLICATE K ...
- mysql 插入重复值 INSERT ... ON DUPLICATE KEY UPDATE
向数据库插入记录时,有时会有这种需求,当符合某种条件的数据存在时,去修改它,不存在时,则新增,也就是saveOrUpdate操作.这种控制可以放在业务层,也可以放在数据库层,大多数数据库都支持这种需求 ...
- INSERT ... ON DUPLICATE KEY UPDATE Syntax
一 mybatis中返回自动生成的id 当有时我们插入一条数据时,由于id很可能是自动生成的,如果我们想要返回这条刚插入的id怎么办呢.在mysql数据中我们可以在insert下添加一个selectK ...
- 可遇不可求的Question之INSERT … ON DUPLICATE KEY UPDATE 语法篇
MySQL 自4.1版以后开始支持INSERT … ON DUPLICATE KEY UPDATE语法,使得原本需要执行3条SQL语句(SELECT,INSERT,UPDATE),缩减为1条语句即可完 ...
- 翻译:insert on duplicate key update(已提交到MariaDB官方手册)
本文为mariadb官方手册:INSERT ON DUPLICATE KEY UPDATE的译文. 原文:https://mariadb.com/kb/en/insert-on-duplicate-k ...
- Mysql中INSERT ... ON DUPLICATE KEY UPDATE的实践
转: Mysql中INSERT ... ON DUPLICATE KEY UPDATE的实践 阿里加多 0.1 2018.03.23 17:19* 字数 492 阅读 2613评论 2喜欢 1 一.前 ...
- mysql INSERT ... ON DUPLICATE KEY UPDATE语句
网上关于INSERT ... ON DUPLICATE KEY UPDATE大多数文章都是同一篇文章转来转去,首先这个语法的目的是为了解决重复性,当数据库中存在某个记录时,执行这条语句会更新它,而不存 ...
- MySQL的INSERT ··· ON DUPLICATE KEY UPDATE使用的几种情况
在MySQL数据库中,如果在insert语句后面带上ON DUPLICATE KEY UPDATE 子句,而要插入的行与表中现有记录的惟一索引或主键中产生重复值,那么就会发生旧行的更新:如果插入的行数 ...
- INSERT ... ON DUPLICATE KEY UPDATE Syntax 专题
ON DUPLICATE KEY UPDATE :不用用于批量,除 insert into t1 select * from t2 on duplicated key update k1=v1,k2 ...
随机推荐
- 云栖大会day2总结 上午
第二天上午主要是参与了开发者专场 上 09:00-09:40 线上线下融合时代的工程师成长 李佩 饿了么高级算法总监 09:40-10:20 如何统一阿里巴巴代码规范:探寻工程师文化之路 玄坛 阿里巴 ...
- Confluence安装部署
前言:Confluence是一个专业的企业知识管理与协同软件,可以用于构建企业wiki.通过它可以实现团队成员之间的协作和知识共享.现在大多数公司都会部署一套Confluence,用作内部WiKi. ...
- hbuilder 打包 vueAPP
1:设置状态栏颜色 在manifest.json 找到 plus 下添加 "statusbar": { "immersed": true/*沉浸式状态栏*/ 设 ...
- mysql Table 'user' is marked as crashed and should be repaired
myisamchk -f x:\xxxxxxxxx\MySQL\data\mysql\*.MYI
- 浅析MVC模式与三层架构的区别
浅析MVC模式与三层架构的区别 三层架构和MVC是有明显区别的,MVC应该是表现模式(三个加起来以后才是三层架构中的UI层).三层架构(3-tier application) 通常意义上的三层架构就是 ...
- JVM性能优化读后笔记
java性能优化权威指南读后笔记 三重境界 1.花似雾中看:对于遇到的额问题还看不清,不知道真真假假,是是非非. 2.悠然见南山:虽然刚开始对这个领域还不清楚,但随着时间推移,你对它有许多自己的见解, ...
- IIS7/8下提示 HTTP 错误 404.13 - Not Found 请求筛选模块被配置为拒绝超过请求内容长度的请求
IIS7的设置和IIS6有很多不同之处,这里提到的的是一个上传附件大小设置的问题. HTTP 错误 404.13 - Not Found 请求筛选模块被配置为拒绝超过请求内容长度的请求. 原因:Web ...
- crm开发之用户ModelForm定制和密码加密
写了这么多的定制 功能.终于可以定制一下了!因为是 stark 和 rbac 两个组建. 一起使用. 所以在这里,再记录一下.需要注意的点: 先放出 目录结构: 先从 stark 开始.使用star ...
- Tomcat7 目录详解
1.bin:该目录下存放的是二进制可执行文件,如果是安装版,那么这个目录下会有两个exe文件:tomcat6.exe.tomcat6w.exe,前者是在控制台下启动Tomcat,后者是弹出UGI窗口启 ...
- java多线程管理 concurrent包用法详解
我们都知道,在JDK1.5之前,Java中要进行业务并发时,通常需要有程序员独立完成代码实现,当然也有一些开源的框架提供了这些功能,但是这些依然没有JDK自带的功能使用起来方便.而当针对高质量 ...