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

推荐订阅源

博客园 - 司徒正美
T
The Blog of Author Tim Ferriss
F
Fortinet All Blogs
Martin Fowler
Martin Fowler
罗磊的独立博客
The GitHub Blog
The GitHub Blog
L
LangChain Blog
A
About on SuperTechFans
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
D
DataBreaches.Net
宝玉的分享
宝玉的分享
U
Unit 42
阮一峰的网络日志
阮一峰的网络日志
Last Week in AI
Last Week in AI
N
Netflix TechBlog - Medium
The Cloudflare Blog
Microsoft Azure Blog
Microsoft Azure Blog
H
Help Net Security
美团技术团队
大猫的无限游戏
大猫的无限游戏
雷峰网
雷峰网
爱范儿
爱范儿
酷 壳 – CoolShell
酷 壳 – CoolShell
MongoDB | Blog
MongoDB | Blog

博客园 - 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 报名记录,但是没有新增报名记录,两个请求程序判定都不存在记录,都会先后新增一条新的报名记录。

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

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