mysql中insert并发问题(on DUPLICATE KEY UPDATE)

 更新时间:2023年01月09日 10:59:39   作者:方才兄  
本文主要介绍了mysql中insert并发问题(on DUPLICATE KEY UPDATE),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

小编最近在项目中,遇到了一个问题,因为并发insert造成了脏数据,主要场景是:

  • 根据查询数据库的结果:存在,则进行更新;不存在,则进行新增;
  • 还有一个场景需求:若已存在,则仅查询;不存在,则进行新增;

百度发现,mysql已经为我们提供了相应的sql语句去实现这些场景。

一、insert,存在则更新,不存在则新增

语法:on DUPLICATE KEY UPDATE

1、表结构如下:

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列

插入初始数据:

insert into testMfc values (null, 1,'1',30),(null,2,'2',40)

2、sql语句 

已存在,则更新:(影响行数为:2,如果使用mybatis,返回值 int =2,同时该语句可返回当前 主键)

 insert into testMfc values (null, 1,'1',30) on duplicate key update num = 1;

 不存在,则新增:(影响行数为:1,如果使用mybatis,返回值 int =1,同时该语句可返回当前 主键)

insert into testMfc values (null, 3,'3',50) on duplicate key update num = 1;

 

3、批量插入,某一条记录存在,则更新;其余进行新增

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语法:(与该表无关,则用作语法参考)

@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,该语句 可以 返回当前 主键)
 insert ignore into testMfc values (null,1,'1',123);

三、总结

mysql还提供了其他原子性操作,比如说:insert,若已存在,则先删除再新增,个人觉得可以使用存在则更新操作代替,所以此处就不做介绍,希望对你们有用。

备注: 网上有人提问,on DUPLICATE KEY UPDATE 在mysql客户端可以正常使用,但是在mybatis就没有效果,既不更新也不新增,同时语句还不报错。小编刚也遇到了“类似情况”,后来发现是参数传错了,粗心了呀。还有一个是sql语句insert的时候,将id也赋值了,这个时候就是主键冲突了。可能不是我们想要的自定义“唯一索引”

 到此这篇关于mysql中insert并发问题(on DUPLICATE KEY UPDATE)的文章就介绍到这了,更多相关mysql insert并发内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Mysql存储引擎详解

    Mysql存储引擎详解

    存储引擎其实就是如何实现存储数据,如何为存储的数据建立索引以及如何更新,查询数据等技术实现的方法。本文我们来详细探讨下MySQL中的几个存储引擎(MyISAM、InnoDB、archive、MERGE)的相关知识
    2016-12-12
  • Mysql事务隔离级别原理实例解析

    Mysql事务隔离级别原理实例解析

    这篇文章主要介绍了Mysql事务隔离级别原理实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • Spark SQL常见4种数据源详解

    Spark SQL常见4种数据源详解

    这篇文章主要介绍了Spark SQL常见4种数据源(详细),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,,需要的朋友可以参考下
    2019-06-06
  • MySQL进阶之索引

    MySQL进阶之索引

    索引就是一种数据结构,这种结构类似,链表,树等等。但是比它们要复杂的多,索引(index)是帮助MySQL高效获取数据的数据结构(有序),本文详细介绍了MySQL索引,感兴趣的同学可以参考阅读
    2023-04-04
  • Mysql中varchar类型一些需要注意的地方

    Mysql中varchar类型一些需要注意的地方

    这篇文章主要介绍了Mysql中varchar类型一些需要注意的地方,帮助大家更好的理解和学习MySQL,感兴趣的朋友可以了解下
    2021-01-01
  • mysql分表之后如何平滑上线详解

    mysql分表之后如何平滑上线详解

    项目开发中,我们的数据库数据越来越大,随之而来的是单个表中数据太多,以至于查询书读变慢,当出现这种情况时,我们可以考虑分表,这篇文章主要给大家介绍了关于mysql分表之后如何平滑上线的相关资料,需要的朋友可以参考下
    2021-10-10
  • windows下安装、卸载mysql服务的方法(mysql 5.6 zip解压版安装教程)

    windows下安装、卸载mysql服务的方法(mysql 5.6 zip解压版安装教程)

    这篇文章主要介绍了windows下安装、卸载mysql服务的方法(zip解压版安装),需要的朋友可以参考下
    2016-06-06
  • mysql-joins具体用法说明

    mysql-joins具体用法说明

    这篇文章主要介绍了mysql-joins具体用法说明,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • MySql5.6使用validate password 插件加强密码强度的安装及使用方法

    MySql5.6使用validate password 插件加强密码强度的安装及使用方法

    在mysql5.6中使用validate password插件加强密码强度,支持密码的强度要求,是一款非常好用的密码加强插件,下面小编通过本文给大家介绍MySql5.6使用validate password 插件加强密码强度的安装及使用方法,小伙伴们一起学习吧
    2016-07-07
  • mysql 5.5 安装配置方法图文教程

    mysql 5.5 安装配置方法图文教程

    这篇文章主要为大家分享了mysql 5.5安装配置方法图文教程,感兴趣的朋友可以参考一下
    2016-11-11

最新评论