A和B接口同时修改table字段,无法确认调用顺序

本文涉及的产品
云原生网关 MSE Higress,422元/月
容器镜像服务 ACR,镜像仓库100个 不限时长
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 在互联网应用开发中,经常会碰到多个接口同时需要修改数据库表字段的情况。然而,由于无法确认接口调用的顺序,可能会导致数据冲突和一致性问题。本文将介绍一种解决这一问题的方法,通过合理的设计和技术手段,确保同时修改table字段的操作能够顺利进行,数据一致性得到保障。

先描述下问题原因,我先文字描述,再画了个流程图。

描述

AB两个接口更新同一个表的字段,但是以B接口下发数据为准,上游调用A接口的同时调用C接口,C接口再同时调用B接口,理论情况下更新时间是按着A先插入了tabel的字段,B再进行更新,最终数据是以B接口下发数据为准的,但由于A接口下发业务逻辑复杂,导致短时间A接口未提交事务时B接口被调用就进行了更新并提交事务导致A接口的事务提交覆盖了B操作,但更可怕的就是A还未提交事务,表中无数据可更新,B无法更新的情况如何更新数据?目前方案在B接口调用时放入缓存数据,在A接口被调用时缓存中有数据则更新缓存中的数据,没有则表明此时B还未被调用则不更新,常规的发生异常或者B后提交事务可以解决,但是A未提交事务时,B无法更新的情况如何处理?

image.png

然后说下场景:order服务统一下发数据,异步调用RPCa和RPCc,order服务不关心AC是否调用成功,A调用失败也不会回滚C,C同理。A插入数据,B根据条件更新table中的某些数据。

问题

A事务还未提交时,B被调用,B无法更新数据

A下发数据异常导致B无法更新数据

在什么节点下删除缓存

是分布式事务吗?

当然不是,AC被调用就是线程隔离的,并且其中一个事务回滚不影响另一个事务。

思路

A就不需要insert所需数据,调整字段类型为null,当B被调用时更新。但是既然无法保证调用顺序,作废

是否能够保证B永远在A被调用后执行?不能

在B被调用就放入缓存,然后Ainsert的时候取缓存的值,缓存有数据ok,没数据不更新,在A insert提交事务后再次触发判断缓存是否有数据,有更新,无的话就说明B还未被调用,B正常去更新就好了,这样只要B成功调用不管是否更新,A被调用时提交事务前后都能更新数据,如果A提交了事务缓存都没值,B也能顺利更新,即便A事务发生回滚再次被调用时也会更新成正确数据。代码比较简单就不上了。

4.能不能当B被调用时先查询是否有数据,没有的话先阻塞,等A提交事务后再被唤醒?可能不行,因为接口肯定调用就超时了。

5.删除缓存节点的话,等业务流程关闭的时候进行删除就可以了。
  1. 并发控制机制
    为了解决同时修改table字段的调用顺序问题,我们需要引入并发控制机制。最常用的并发控制机制是事务。事务提供了一种机制,可以保证一组操作作为一个逻辑单元被执行,要么全部成功,要么全部失败。在这种方式下,我们可以通过对数据库操作进行事务封装,确保同时修改table字段的一致性。

  2. 设计适应并发修改的数据结构
    为了适应同时修改table字段的场景,我们需要针对具体的应用场景设计适合的数据结构。常见的做法是引入版本号或时间戳字段,并将其作为修改字段时的判断条件。这样,在并行修改时,只有满足特定条件的修改操作会被执行,避免了数据冲突。

  3. 分离读写操作
    为了进一步提高并发性能,可以将读操作与写操作进行分离。通过引入读写分离机制,将读操作路由到读库,将写操作路由到写库,可以提高系统的并发处理能力。这样,在同时修改table字段的情况下,不会出现因为读写操作的争抢而导致的性能瓶颈。

  4. 异步消息队列
    另一种解决同时修改table字段的调用顺序问题的方法是使用异步消息队列。当多个接口需要修改同一数据库表的字段时,可以将这些修改操作作为消息发布到消息队列中。然后,通过消费者从消息队列中获取消息,并按照特定的顺序进行处理。这样,即使无法确定接口调用的顺序,也可以通过消息队列的有序性保证数据一致性。

  5. 数据库级别的锁机制
    除了事务和异步消息队列,数据库本身也提供了并发控制的手段。例如,通过行级锁或表级锁,可以限制同时修改table字段的操作。在数据库中,可以根据具体情况选择适合的锁机制,在保证数据一致性的前提下,提高系统的并发性能。

  6. 结论
    同时修改数据库表字段的调用顺序是互联网应用开发中常见的问题。通过合理的设计和技术手段,我们可以解决这一问题,确保数据一致性和系统的并发性能。在具体的应用场景中,可以根据需求选择适合的并发控制机制,并结合数据结构设计、读写分离、异步消息队列和数据库级别的锁机制等手段,保证同时修改table字段的操作能够顺利进行。

参考文献:
[1] Gray, J. D., & Reuter, A. (1993). Transaction processing: concepts and techniques (Vol. 75). Elsevier.
[2] Shi, K., Wang, S., Jin, H., Wang, X., & Luo, J. (2016). A distributed low-latency Transaction Processing System for Web Services. IEEE Transactions on Services Computing, 9(4), 545-558.
[3] Stonebraker, M., Hellerstein, J. M., & Hamilton, J. (2013). Architecture of a database system. Foundations and Trends® in Databases, 5(4), 197-246.

目录
相关文章
|
缓存 测试技术
podam mock 对象部分字段没有赋值问题
本文主要分析使用 podam mock 对象时,部分字段无法自动赋值的原因,并给出解决方案。
|
6月前
|
Python
定义字段
定义字段。
27 1
|
存储
PG11新特性解读:新增非空默认值字段不需要重写表
PG11新特性解读:新增非空默认值字段不需要重写表
170 1
|
缓存
A和B接口同时修改table字段,无法确认调用顺序
先描述下问题原因,我先文字描述,再画了个流程图。
106 0
A和B接口同时修改table字段,无法确认调用顺序
|
SQL 分布式计算 大数据
Column 对象_操作_别名和类型 | 学习笔记
快速学习 Column 对象_操作_别名和类型
108 0
Column 对象_操作_别名和类型 | 学习笔记
|
Scala 开发者
覆写字段注意事项和细节说明2|学习笔记
快速学习覆写字段注意事项和细节说明2。
104 0
覆写字段注意事项和细节说明2|学习笔记
|
Java 程序员 编译器
覆写字段注意事项和细节说明1|学习笔记
快速学习覆写字段注意事项和细节说明1。
106 0
|
存储 Java 索引
Class文件结构介绍[访问标志,类索引,父类索引,接口索引集合]
在常量池结束后,紧接着的两个字节代表访问标志(access_flags),这个标志用于识别一些类或者接口层次的访问信息,包括:这个Class是类还是接口,是否定义为public类型,是否定义为abstract类型,如果是类的话是否被声明为final等,
Class文件结构介绍[访问标志,类索引,父类索引,接口索引集合]
|
SQL Java 数据库
一个工具类搞定 CRUD 的创建人、修改人、时间等字段赋值!
数据库设计过程中,我们往往会给数据库表添加一些通用字段,比如创建人、创建时间、修改人、修改时间,在一些公司的设计过程中有时会强制要求每个表都要包含这些基础信息,以便记录数据操作时的一些基本日志记录。
基类、接口的应用——表单控件:一次添加、修改一条记录,一次修改多条记录。(上)
好久没发帖子了,又加了不少的功能呀。(图片仅是测试,不代表什么表情。) 本来我也想写一个2007的总结的,但是看到很多人都写了,我就不凑热闹了,写点和代码有关系的吧。 写作原因: 1、在项目里做得最多的操作恐怕就是保存数据了,总是要写一大堆的代码,能不能简单一点呢?2005来了,似乎可以减少一些代码,但是03里怎么办呢? 2、基类、接口、策略模式,好多高手都讨论过了,但是都是理论上的,在实践中如何应用呢?在webform 里面又怎么使用呢? 目的: 1、做一个“控件”来应对各种表单的录入,包括一次保存一条记录、一次保存多条记录。
1018 0