mysql中insert并发问题(on DUPLICATE KEY UPDATE)
脚本之家 / 编程助手:解决程序员“几乎”所有问题!
脚本之家官方知识库 → 点击立即使用
小编最近在项目中,遇到了一个问题,因为并发insert造成了脏数据,主要场景是:
- 根据查询数据库的结果:存在,则进行更新;不存在,则进行新增;
- 还有一个场景需求:若已存在,则仅查询;不存在,则进行新增;
百度发现,mysql已经为我们提供了相应的sql语句去实现这些场景。
一、insert,存在则更新,不存在则新增
语法:on DUPLICATE KEY UPDATE
1、表结构如下:
1 2 3 4 5 6 7 8 | CREATE TABLE `testMfc` ( `id` int (11) NOT NULL AUTO_INCREMENT, `age` int (11) DEFAULT NULL , ` name ` varchar (20) DEFAULT NULL , `num` int (11) DEFAULT NULL , PRIMARY KEY (`id`), UNIQUE KEY `uk_01` (`age`,` name `) ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 |
注意:想要使用该语法,必须利用“唯一索引”或者“主键索引”,只有产生“索引冲突”,该语法才能正常生效。
此处建立唯一索引:age列和name列
插入初始数据:
2、sql语句
已存在,则更新:(影响行数为:2,如果使用mybatis,返回值 int =2,同时该语句可返回当前 主键)
不存在,则新增:(影响行数为:1,如果使用mybatis,返回值 int =1,同时该语句可返回当前 主键)
insert into testMfc values (null, 3,'3',50) on duplicate key update num = 1;
3、批量插入,某一条记录存在,则更新;其余进行新增
1 2 3 4 5 6 | insert into testMfc values ( null , 3, '3' ,300), ( null , 4, '4' ,400), ( null , 5, '5' ,500), ( null , 2, '2' ,200) on duplicate key update num = values (num); |
更新:age = 2 和 age =3 的num属性,新增age = 4 和 5 的数据
注意: num = values(num) ,此处的格式,必须是 values(列名),才能更新到对应的行。
mybatis语法:(与该表无关,则用作语法参考)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | @Insert ({ "<script>" , "insert into weekly_item (weekly_id, weekly_task_name," + "task_id, plan, project_id,duty_user_key, status, copy_status," + "create_at, update_at, comment_id,complete)" + "<foreach collection='insertList' item='item' open='values ' separator=','> " + "(#{item.weeklyId,jdbcType=INTEGER}," + "#{item.weeklyTaskName,jdbcType=VARCHAR}," + "#{item.taskId,jdbcType=INTEGER}," + "#{item.plan,jdbcType=VARCHAR}," + "#{item.projectId,jdbcType=INTEGER}," + "#{item.dutyUserKey,jdbcType=VARCHAR}," + "#{item.status,jdbcType=TINYINT}," + "#{item.copyStatus,jdbcType=TINYINT}," + "now()," + "now()," + "#{item.commentId,jdbcType=INTEGER}," + "#{item.complete,jdbcType=VARCHAR})" + "</foreach>" + "ON DUPLICATE KEY UPDATE " + "complete = VALUES(complete)" , "</script>" }) void insertBatchOrUpdate( @Param ( "insertList" ) List<WeeklyItem> copyItemList); |
二、insert,存在则不进行任何操作;不存在则新增
语法:insert ignore into 表名
1、sql语句
注意:
- 已存在:(影响行数为:0,如果使用mybatis,返回值 int =0,该语句不能 返回当前 主键)
- 不存在则新增:(影响行数为:1,如果使用mybatis,返回值 int =1,该语句 可以 返回当前 主键)
三、总结
mysql还提供了其他原子性操作,比如说:insert,若已存在,则先删除再新增,个人觉得可以使用存在则更新操作代替,所以此处就不做介绍,希望对你们有用。
备注: 网上有人提问,on DUPLICATE KEY UPDATE 在mysql客户端可以正常使用,但是在mybatis就没有效果,既不更新也不新增,同时语句还不报错。小编刚也遇到了“类似情况”,后来发现是参数传错了,粗心了呀。还有一个是sql语句insert的时候,将id也赋值了,这个时候就是主键冲突了。可能不是我们想要的自定义“唯一索引”
到此这篇关于mysql中insert并发问题(on DUPLICATE KEY UPDATE)的文章就介绍到这了,更多相关mysql insert并发内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
微信公众号搜索 “ 脚本之家 ” ,选择关注
程序猿的那些事、送书等活动等着你
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 reterry123@163.com 进行投诉反馈,一经查实,立即处理!
相关文章
windows下安装、卸载mysql服务的方法(mysql 5.6 zip解压版安装教程)
这篇文章主要介绍了windows下安装、卸载mysql服务的方法(zip解压版安装),需要的朋友可以参考下2016-06-06MySql5.6使用validate password 插件加强密码强度的安装及使用方法
在mysql5.6中使用validate password插件加强密码强度,支持密码的强度要求,是一款非常好用的密码加强插件,下面小编通过本文给大家介绍MySql5.6使用validate password 插件加强密码强度的安装及使用方法,小伙伴们一起学习吧2016-07-07
最新评论