Mysql 数据库并发事物导致ABA问题排查解决

news/2024/11/30 8:34:45/文章来源:https://www.cnblogs.com/crazy-dev/p/18568370

问题描述

一个更新计费参数接口,按钮连点导致数据未更新问题。

背景

接口内容逻辑,在一个事物内,先保存更新计费参数,再根据计费参数,重新计算费用,并刷新计费单,结算单,支付单等单据金额信息。

按理来讲,这个接口是具备幂等性的,因为即便多次更新,也只是重新计算一遍,数据结果不会改变。
但这个问题现象是两次并发操作导致数据不发生变化,相当于一次操作更新了,但另一次操作给还原了。

过程分析

事物1 事物2
select * from table where id = ?; // 对数据做校验 select * from table where id = ?; // 对数据做校验
// 事物2 更新语句先执行,锁住当前行,等待事物2结束 update table set fee = ?,update_time = ? where id = ?; //保存费用配置并通过更新当前事物数据为最新行数据

//调用统一刷新费用方法
select * from table where id = ?; // 查询最新数据
update table set fee = ?, amount = ?, update_time = ? where id = ?; //更新业务数据(根据fee新值,计算出新值 amount 并更新)
//事物结束,释放行锁
update table set fee = ?, amount = ?,update_time = ? where id = ?; //保存费用配置并通过更新当前事物数据为最新行数据,(因另一事物已更新,SQL执行成功,但因数据一样,未实际更新数据)
//调用统一刷新费用方法
select * from table where id = ?; // 查询最新数据(MVCC 旧数据)
update table set fee = ?, amount = ?,update_time = ? where id = ?; //更新业务数据(导致根据fee旧值,计算出旧值 amount 并更新覆盖新值 )

因操作连点,两个事物在1秒内完成,因此更新时间的差额在毫秒级,数据库更新时间字段使用 timestamp 类型精确到秒,导致事物2执行完后,事物1第一次更新时,更新数据和数据库行数据是一致的,所以更新sql执行了,但没有实际更新数据,导致当前事物还是快照读,因此当前事物看不到最新行数据,还是使用事物1原本的数据版本号,也就是老数据。
所以在统一刷新费用方法中,重新根据id查询时,还是老数据,导致费用数据又备更新为老数据。

解决办法

  • 数据库更新时间字段使用 timestamp(3),精确到毫秒级,保证更新成功,事物当前读,可以获取到最新行数据。
  • 事物开头主动锁行,使用当前读,避免使用快照读:select * from table where id = ? for update,保证获取最新数据并阻塞其他事物。
  • 操作增加分布式锁,锁粒度为当前订单,避免同时操作同一订单的修改操作。
  • 前端按钮增加连点控制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/840959.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

工程化开发谷歌插件到底有爽

工程化开发谷歌插件到底有爽谷歌插件开发本质上就是写一些 html + js + css谷歌开发心得吧 manifest.json 文件{"manifest_version": 3,"name": "发布助手","version": "3.0","description": "前端资源监测&…

12-渗透测试

1、水平越权&垂直越权漏洞实验水平越权lucy用户登入成功后,将url的username参数由lucy改为kobe,即可查看到kobe的信息,实现水平越权垂直越权使用低权限用户pikachu访问添加用户页面,行使管理员admin用户的添加用户权限用户添加成功,实现垂直越权2、密码修改逻辑漏洞实…

vxe-modal 实现弹窗多窗口

官网:https://vxeui.com<template><div><p><vxe-button content="点击弹出" @click="openEvent"></vxe-button></p></div> </template><script> import { VxeUI } from vxe-pc-ui export default …

redis 流量增加过多问题排查解决

背景 Java项目,使用Redis集群。 现象 Redis集群,单台流量增加过多。 在redis服务器上:iftop -npP排查过程 发现流量上涨是同一台机器IP尾号3。到这台机器上查看。 top 命令查看进程idtop -H -p 1748 查看具体线程信息,可以看到,有三个线程执行100多小时,而且占用较多cpu…

RX23E-B系列微控制器是工业传感器设备的理想选择!R5F523E5B介绍,EFR32BG13P732F512GM48-D蓝牙/TH58NVG2S3HTAI0存储IC

RX23E-B系列微控制器是工业传感器设备的理想选择!R5F523E5B介绍,EFR32BG13P732F512GM48-D蓝牙/TH58NVG2S3HTAI0存储ICRX23E-B 系列微控制器具有内置模拟前端 (AFE),是工业传感器设备的理想选择。 与上一代的 RX23E-A 相比,RX23E-B 的24 位 Delta Sigma 模/数转换器在高速性…

100ASK_IMX6ULL-PRO 数码相框扩展项目:支持打开阅读 TXT 文件

背景说明 本篇内容基于百问网嵌入式Linux项目数码相框与文件浏览器和嵌入式Linux电子书阅读器 需求:在文件浏览器界面中支持双击打开TXT类型文件,进入新界面进行文本阅读和翻页控制。 实现思路说明 浏览器界面中响应双击操作,识别TXT类型文件成功后进入阅读器界面。可参考项…

mysql数据库聚合与拆分

1. 背景在用户使用的时候会有统计数据的情况,在多表联查的时候分类时会有,同一个类型出现多次,然后任务需区是出现一次类型名 2. 聚合查询 GROUP_CONCAT(聚合字段) group_by(聚合字段)SELECT report.serialNumber as 病人编号, GROUP_CONCAT(label.lableName) AS &q…

GIS与数字孪生融合:打造智能3D空域管理平台

在数字化转型的浪潮中,地理信息系统(GIS)技术正以其独特的空间分析能力,为城市规划和管理带来革命性的变化。今天,我们将探讨一个前沿话题:基于GIS技术的数字孪生3D空域规划与飞行信息管理平台。 什么是数字孪生?数字孪生,简而言之,就是物理世界中的实体在数字世界中的…

iOS内购——自动续订型会员

原文链接:https://blog.csdn.net/HMOnlyou/article/details/139446159 一、内购支付流程 用户选择商品,发起购买操作,支付完成(会从AppleID账号关联的支付宝/微信 /银行卡完成扣款); 拿到APP本地生成的票据信息发送到苹果服务器验证有效性。1)APP端可以直接向苹果服务器…

微信小游戏sdk接入支付和登录,解决了wx原生不支持ios支付的痛点

本文介绍了微信小游戏sdk登录支付的接入。支付又分为 android支付和 ios支付。由于微信小游戏内不支持ios支付, 通过引入客服会话的方式实现。 侧重于服务器方向,对于复杂的验证签名、解密算法部分提供了Go版本的代码支持【原创】前情提要 微信小游戏是小程序的一种。 项目接入…

vxe-form table 表单修改数据校验错误提示的样式

官网:https://vxeui.com<template><div><vxe-formv-bind="formOptions"@submit="submitEvent"@reset="resetEvent"></vxe-form></div> </template><script> import { VxeUI } from vxe-pc-uiexport …

vxe-form table 设置表单上下布局

官网:https://vxeui.com<template><div><vxe-formv-bind="formOptions"@submit="submitEvent"@reset="resetEvent"></vxe-form></div> </template><script> import { VxeUI } from vxe-pc-uiexport …