mysql 并发操作的问题

2021-12-25 10:53:16 +08:00
 awanganddong

业务场景是这样的,单一用户的账号,可能会牵扯到并发问题。 就是在同一秒内,该用户的余额会频繁更新。 首先加锁这种情况不太适合。 单纯从 mysql 自身这个问题能否解决? 或者说把金额存入内存。

这是知乎的一个提问

https://www.zhihu.com/question/61484424

3075 次点击
所在节点    MySQL
13 条回复
fkdog
2021-12-25 11:44:21 +08:00
单个用户频繁更新算不上并发。直接加行锁完事了。
就算一秒钟更新 20 下,行锁都是绰绰有余。
你觉得不合适大概率只是你自己觉得,跑一下压测就知道了,大多数情况只是杞人忧天。。
0ZXYDDu796nVCFxq
2021-12-25 11:48:56 +08:00
每次的变动还得计流水吧
Saxton
2021-12-25 11:57:30 +08:00
“就是在同一秒内,该用户的余额会频繁更新。 首先加锁这种情况不太适合。”
你这种情况就适合的就是行锁,为什么不太适合
notejava
2021-12-25 12:12:00 +08:00
乐观锁
swcat
2021-12-25 12:30:32 +08:00
加个版本,
update xx_table set balance = :balance where id = :id and version_id = :version_id
根据实际情况修改

或者加个
先锁住: select for update
再判断: 这个也得判断下, 判断状态能否更新, 结果得大于 0 吧, 状态可以改吧....
后更新: 更新数据

id 为为主键
mitu9527
2021-12-25 13:52:18 +08:00
一般代码都是先读后写,所以除非你代码就是纯更新,否则先去开事务。
搞清楚并发问题所竞争的资源到底是啥。到底是这条记录还是这条记录里面的金额。
如果只是金额,看看能不能用 update ... set money = money + n 解决。
如果上面的方式不行,可以考虑用悲观并发控制策略和乐观并发控制策略,也就是大家常说的悲观锁和乐观锁。选那种,取决于发生的频率和引发的后果到底有多大。
悲观锁最简单的就是用 select for update 或者 redis 来实现,自己根据情况选,两种方式也都不是完美的,引入那种你认为合适的就可以了。
乐观锁一般就是用版本号来实现。
根据情况看看是否有必要做幂等判断,比如状态判断什么的。
7911364440
2021-12-25 14:36:11 +08:00
把金额也作为更新条件呢?
update t set money = money+n where id = :id and money = :money
awanganddong
2021-12-25 15:56:33 +08:00
业务场景就是用户之间赠送礼物,比如同一秒多个用户给一个用户 A 送礼物。
如果这时候加行锁的话,用户这条记录就被锁定了。
问题就在于用户这张数据表属于热表,该条记录的其他字段在其他业务也有更新操作。
担心行锁的话,就会出现死锁的情况。

更可怕的一点,我们这边是主从库配置,现在我暂时把代码切换成查主库,可以降低该概率的发生。
现在对用户操作,都有日志记录。

既然如此,现在我能发现问题,但是对于怎么成本最小的解决这个问题,或者优化这个问题,现在没有太大思路。
awanganddong
2021-12-25 16:01:02 +08:00
类似于客观锁这种机制,所带来问题就是用户操作的失败。
这从代码层面其实没有太大问题,但是对于产品侧,用户体验方面,这个问题就比较严重。
如果乐观锁校验失败,这个就更新失败。
awanganddong
2021-12-25 16:02:10 +08:00
我先压测下关于频繁更新的行锁情况吧。这个很靠谱的。
sagaxu
2021-12-25 17:06:12 +08:00
行锁每秒 10W 次是扛得住的,高配机器能做到 20W 次
fiypig
2021-12-25 19:04:46 +08:00
行锁就可以,又不是表锁
git00ll
2021-12-25 20:21:04 +08:00
for update 没问题的,每秒 4000 次

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/824363

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX