前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >业务需求:数据库如何保证先查询后插入/更新 原子性?

业务需求:数据库如何保证先查询后插入/更新 原子性?

作者头像
一枝花算不算浪漫
发布2019-11-01 15:08:22
4.4K1
发布2019-11-01 15:08:22
举报

一、业务需求:

当操作积分用户表时,如果accountId在表中没有数据,那么我们新增一条数据,设置用户积分。如果accountId在表中有数据,我们需要更新用户积分。

这个操作简单来说就是: 

在单线程下 我们先查询后处理当然没有问题,但是在并发下问题就显而易见了,系统里可能同时插入两条一样的accountId数据。

二、问题解决:

解决方式一: ON DUPLICATE KEY UPDATE

数据库中account_id设置唯一索引,当发现account__id已经存在时,会执行update操作,不存在时会执行insert操作。

一行sql语句就能完成两种操作,保证了原子性。

sql语句如下:

添加单元测试,查看耗时以及查验数据库在并发下数据是否正确。

代码隐去业务代码,如下:

查看打印的日志,共耗时:22690ms

数据库数据能够保持正确性

解决方式二: 使用分布式锁

这个耗时比第一种方式差很多,所以没有测试完就放弃了。

因为高并发的情况下 锁的抢占很激烈,这里很多时间都耗费在锁的抢占上,没有抢占到锁的线程需要重试而不能失败,类似于CAS操作,所以这种方式不适合当前业务。

解决方式三: INSERT INTO SELECT

此种方式也是最优的,耗时:20010ms

sql语句如下:

查询accountId不存在时结果:

查询accountId存在时结果:

这里需要注意的是,此sql语句在Mapper.xml中是insert语句:

三、原理分析

1、ON DUPLICATE KEY UPDATE

mysql "ON DUPLICATE KEY UPDATE" 语法:

如果在INSERT语句末尾指定了ON DUPLICATE KEY UPDATE,并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值,则在出现重复值的行执行UPDATE;如果不会导致唯一值列重复的问题,则插入新行。

2、 INSERT INTO SELECT

INSERT INTO SELECT 语句从一个表复制数据,然后把数据插入到一个已存在的表中。目标表中任何已存在的行都不会受影响。

其中使用到了dual虚拟表, 根据mysql的官方定义:

DUAL is purely for the convenience of people who require that all SELECT statements should have FROM and possibly other clauses. MySQL may ignore the clauses. MySQL does not require FROM DUAL if no tables are referenced.

官方的解释说:纯粹是为了满足select … from…这一习惯问题,mysql会忽略对该表的引用。所以上面的语句from dual可以去掉。

简言之,from dual完全是一个可有可无的东西。只是为了方便使用select 语句中喜欢带上from的开发者。

例如我们使用select 1 查询等价于select 1 from dual

四、总结

到了这里就分析完了,如果大家有更好的解决方案也可以拿出来学习下,文中如有问题恳请大家指正一下。

第一种方式会有一个id不是连续自增的问题,具体可以参考文章: https://segmentfault.com/a/1190000017268633

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-10-31 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、业务需求:
  • 二、问题解决:
    • 解决方式一: ON DUPLICATE KEY UPDATE
      • 解决方式二: 使用分布式锁
        • 解决方式三: INSERT INTO SELECT
        • 三、原理分析
        • 四、总结
        相关产品与服务
        云数据库 SQL Server
        腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档