thinkphp6 redis并发解决处理方案
2023-03-29 23:03:03
300
{{single.collect_count}}

并发测试命令:安装apache

ab -c 1000 -n 100 http://www.baidu.com/接口地址请求1000次、每次有100个人同时请求 http://www.baidu.com/api

常规思路(优化&不推荐)

// 业务逻辑:// 用户执行下单操作 // mysql 查询商品库存// 判断物品库存是否充足// 优化1:库存字段设置 unsigned (无符号)即不能是负数假设目前商品库存100件、同时有1w个人下单。虽然商品库存为0了,但是实际生成的订单远远超过规定库存// 优化2:使用事务 (性能 对比缓存来说性能较低 实现起来较为繁琐,需要自己考虑锁超时,加事务)Db::startTrans();... lock(true)...Db::commit();Db::rollback();// 优化3:文件排它锁 fopen、flock(EX | NB)、fclose// 优化4:redis队列 原子性// 优化5:redis 分布式锁 setnx 同一个键值指针生效一次 判断设置内容是否失效 时间戳// 优化6:redis 悲观锁 watch、multi、incr、exec// 优化7:think-queue队列 redis队列一个一个执行

隔离级别

ACID(原子性、一致性、隔离性、持久性)并发一致性:(激活码)丢失更新:A、B同时修改数据,A先,B后,A提交后B提交,B操作覆盖了A的操作,导致A丢失更新。读脏数据:A修改数据,B读取数据;随后A撤销操作,则B读到脏数据。不可重复读:B读取数据,A修改数据,B再次读取数据,发现数据和第一次读时不一致。幻读:A读取了某个范围的数据,B在此范围内插入一条数据;A再次读取,结果不一样。脏读 (回滚)男女朋友分手了,舍不得复合了 备胎咋又有男朋友了呢不可重复读(变化)男女朋友闹矛盾了,男花了银行卡钱,女没告诉男的用了他银行卡钱,男的我钱被银行黑了幻读(多了)男女朋友度蜜月,男花了银行卡钱,父母给男的银行卡打钱了。钱怎么变多了。并发环境下,为解决并发一致性问题保证事务的隔离性,可采取封锁机制。行锁:事务A操作数据时,只封锁被操作的行,事务B可以操作其他行的数据,并发程度高;表锁:事务A操作数据时,封锁整个表,事务B要等A完成才能操作,并发度较低。读写方面数据库锁也分为读锁(共享锁)和写锁(排他锁)。读锁:若事务A加了此锁,A可以对数据进行读取操作,但不能更新;其它事务也可以读,但不能修改;写锁:若事务A加了此锁,A可以对数据进行读和写操作,其它事务不能读写,否则会阻塞。悲观锁,MySQL中InnoDB也提供了乐观锁的实现——MVCC(多版本并发控制)。用通俗的方式解释悲观锁和乐观锁大概是这样:​悲观锁:认为每次操作都会修改数据,每次都在操作前上锁;​乐观锁:认为每次操作都不会修改数据,不上锁,但是会记录一个版本号或者时间戳,用来对比。未提交读:事务修改数据,即使未提交,其它事务依旧可见。已提交读:事务修改数据提交之前,其他事务不可见。可重复读:事务多次读取数据的结果都一样。可序列化:解决了幻读问题。

存储引擎

一般在读操作比较多的情况下,MyISAM的效率更高,因为相比于InnoDB,它维护的东西要少,比如版本号,索引数据等。但是InnoDB支持事务,而且在并发环境下优势显著。至于如何选择存储引擎,应根据具体情况而定。

回帖
全部回帖({{commentCount}})
{{item.user.nickname}} {{item.user.group_title}} {{item.friend_time}}
{{item.content}}
{{item.comment_content_show ? '取消' : '回复'}} 删除
回帖
{{reply.user.nickname}} {{reply.user.group_title}} {{reply.friend_time}}
{{reply.content}}
{{reply.comment_content_show ? '取消' : '回复'}} 删除
回帖
收起
没有更多啦~
{{commentLoading ? '加载中...' : '查看更多评论'}}