高并发情况下,创建和更新时,如何保证数据准确

Posted 栗子~~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高并发情况下,创建和更新时,如何保证数据准确相关的知识,希望对你有一定的参考价值。

文章目录

前言

  如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。
  而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!!


高并发情况下,创建和更新时,如何保证数据准确

1、首先保证代码是正确没有bug的;

2、正确使用数据库的事务;

数据库的事务能保证在同一事务中你执行的这些insert和update语句保证要不一起失败,要不一起成功,起到原子性的作用。

3、对于重复请求的问题、如何设计绕开这个问题

3.1、设置web端防止用户重复提交功能
3.2、服务端接口服务具备幂等性

因为当出现网络错误会导致重传,很多RPC框架和网关都具有自动重试机制;
幂等性操作的特点是多次执行造成的影响和一次执行操作造成的影响是一样的,即对于幂等的方法来说,不用担心重复执行会对系统造成任何改变。

3.3、对于那些业务严谨性比较高的需求时,如何确定请求为重复提交请求

我们这里可以利用数据库的主键唯一约束的特点来保证插入的数据是非重复的,即人为设置主键, 这里我们可以引用第三方服务来专门制作主键,该主键的特点是唯一的。

4 、更新时如何解决ABA问题

4.1、什么是ABA问题?

简单来说,用户短时间发送两个请求:
请求1: 修改字段flag为1
请求2:修改字段flag为2
正常流程:

首先请求1到了,字段flag更新为a,然后请求2到了,字段flag更新为b;
对于ABA问题造成的影响:


简单来说,请求1到了,flag字段更新为a,然后请求2到了,falg字段更新为b,但是请求1更新成功的响应丢失了,调用方没有接受到成功响应,自动重试,flag又更新为a了。

4.2、如何设计避免ABA问题?

这里有个通用的解决方式,就是给你更新哪行数据增加一列version(版本号)
首先version(版本号)要随着你的查询接口返回到页面,当你提交请求时将你的版本号也带到请求参数里,后台服务在更新数据时,需要比较当前版本号与请求中的版本号,是否一致,如果不一致拒接更新,如果一致,更新数据的同时,将版本号+1更新。
注意:这个环节必须是在同一个事务中进行。

具体的SQL示例:

update test set flag = a where version = 1

where条件中,version的值需要页面在更新的时候通过请求传送过来。

加上这个设计后,对于触发ABA问题的请求会出现两种情况:
(1)、请求1更新flag为a的操作成功了,如果更新b的请求2带着旧版本号,那么就会更新失败。
(2)、请求1更新flag为a的操作成功了,请求2带着新版本号,因此请求2更新flag为b也成功了,这时候即使重试请求1,但因为请求1带着旧版本号,那么因为它和请求1带着相同的版本号,因此在请求1更新成功后,版本号已经变了,因此重试请求的更新失败。

无论那种情况,数据库中的数与页面上给用户的反馈都是一致的,这样就可以实现幂等更新并避免了ABA问题。

以上是关于高并发情况下,创建和更新时,如何保证数据准确的主要内容,如果未能解决你的问题,请参考以下文章

高并发情况下,创建和更新时,如何保证数据准确

大厂面试01期高并发场景下,如何保证缓存与数据库一致性?

大厂面试01期高并发场景下,如何保证缓存与数据库一致性?

Kafka在高并发的情况下,如何避免消息丢失和消息重复?kafka消费怎么保证数据消费一次?数据的一致性和统一性?数据的完整性?

mysql在django中开启事务,实现悲观锁和乐观锁

阿里Java面试题剖析:在高并发的情况下如何保证消息的顺序性?