惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

大猫的无限游戏
大猫的无限游戏
MyScale Blog
MyScale Blog
雷峰网
雷峰网
量子位
小众软件
小众软件
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 叶小钗
T
Tailwind CSS Blog
月光博客
月光博客
博客园 - 【当耐特】
博客园_首页
罗磊的独立博客
博客园 - 三生石上(FineUI控件)
IT之家
IT之家
爱范儿
爱范儿
阮一峰的网络日志
阮一峰的网络日志
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
WordPress大学
WordPress大学
The Cloudflare Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
S
SegmentFault 最新的问题
人人都是产品经理
人人都是产品经理
V
V2EX
酷 壳 – CoolShell
酷 壳 – CoolShell

博客园 - tying

fastadmin mongodb 处理及使用 mysql的知识扩展 <论语> fastadmin配合宝塔面板造成cors error 跨域问题 小型在线聊天功能 fastadmin数据库操作 技术文章分享 shopxo学习过程 fastadmin 開發好文章 fastadmin常用前端组件 2024-11-13关于监管特殊停牌炒作股票事件--兼此事件复盘 深入浅出的讲解mysql优化 关于gruop by,where和order by ,以及一些mysql的探讨 fastadmin使用感受 fastadmin命令行模式--command mac 下Fastadmin 框架搭建 Mac电脑php环境搭建 关于php+mysql性能在实际工作中的应用实例 yii2的单元测试 d8的入口文件及引申
一个小并发,引起的数据错误
tying · 2025-10-13 · via 博客园 - tying

1.昨天测试的时候遇到一个并发问题。用户2和用户6同一时间报名参加一个活动,数据除了写入报名表外,还写入了活动表,因此造成了并发问题,导致报名参加的总人数不正确。

再此之前也做过了一次改进,就是开启了事物。

理论上开启事物后,是不会引发写入数据错误问题的。因为事物本身对sql语句进行了加锁操作。但是昨天依然出现了问题,就有排查了一下,先看下日志

用户6增加了一个报名人数

图片

 用户2增加了一个报名人数

图片

这两个人报名后,总报名人数都更新为了17,那么说明他两人在读取报名人数的时候是同一时间,都是16个人。

这里就出现了一个问题,如果事物是枷锁的,那么此时用户2是读不到报名人数的。就只有两种情况了,第一种是事务不加锁,第二种情况是框架的事务没有起作用。

对于第二种我搜了下,没有相关文档,只能追源码。于是我反向搜了事务,发现是事务的读锁确实是不加的,只加了写锁。

图片

mysql的默认隔离级别为可重复读,不加读锁。这张图有个错误,就是可重复读时会出现幻读的,它没有解决这个问题

然后在看下程序

图片

 在此处使用了程序上的加法,因此并发时造成了数据问题。从上图的日志也可以看出问题所在。

这样理论上就诞生了两种解决方案

第一种:修改sql语句,不适用save的方法。使用update 字段+1的方式

第二种:在增加排他锁,在事务完成前,不允许读。

两种方法各有优缺点,此处我打算使用第一种方式,然后进行下测试

在将程序方法修改完后,又出现一个新的并发问题---幻读,

某用户第一次参加活动,连续点击两次。程序会先到数据库中读取报名记录,如果存在,报名人数+1,不存在,新增一条报名记录。

此时两个请求同时运行到select 报名记录,但是没有新增报名记录,两个请求程序判定都不存在记录,都会先后新增一条新的报名记录。

理论上本应该解决的幻读问题,事务并没有解决。

暂时现在前端做了误触处理,后续再看。