实际开发过程中 处理高并发的几种方法

1.创建临时表 该表一个字段 并且设置唯一索引 比如抽奖活动 把奖品编号存入这个字段 ,一个请求过来的时候插入 另外一个请求就无法插入同一个奖品编号,只能等待前一个请求处理完成之后 删掉该表中的这个奖品编号 另外一个请求才能插入同一个奖品编号 这样可以完美控制并发产生脏数据
2.使用select for update 第一步查询锁住 第二步 判断 第三步更新数据
for update的锁表
InnoDB默认是行级别的锁,当有明确指定的主键时候,是行级锁。否则是表级别。

例子: 假设表foods ,存在有id跟name、status三个字段,id是主键,status有索引。

例1: (明确指定主键,并且有此记录,行级锁)

SELECT * FROM foods WHERE id=1 FOR UPDATE;
SELECT * FROM foods WHERE id=1 and name=’咖啡色的羊驼’ FOR UPDATE;
例2: (明确指定主键/索引,若查无此记录,无锁)

SELECT * FROM foods WHERE id=-1 FOR UPDATE;
例3: (无主键/索引,表级锁)

SELECT * FROM foods WHERE name=’咖啡色的羊驼’ FOR UPDATE;
例4: (主键/索引不明确,表级锁)

SELECT * FROM foods WHERE id<>’3’ FOR UPDATE;
SELECT * FROM foods WHERE id LIKE ‘3’ FOR UPDATE;
for update的注意点
for update 仅适用于InnoDB,并且必须开启事务,在begin与commit之间才生效。

3.队列处理 ,把请求交给队列处理 进行异步处理 适用于高并发但不要求实时反馈的场景

4.在存储过程里面 用复合update 语句 完成 查询和更新 更新后面加上判断的条件 这个方式也能有效降低并发产生脏数据情况 但不能完全避免 但是性能比较好

乐观锁

修改版本号,version。

假设数据库中帐户信息表中有一个 version字段,当前值为 1 ;而当前帐户余额字段( balance )为 $100 。

1操作员 A 此时将其读出( version=1 ),并从其帐户余额中扣除 $50( $100-$50 )。

2在操作员 A 操作的过程中,操作员 B 也读入此用户信息( version=1 ),并 从其帐户余额中扣除 $20 ( $100-$20 )。

3 操作员 A完成了修改工作,将数据版本号加一( version=2 ),连同帐户扣 除后余额( balance=$50 ),提交至数据库更新,此时由于
提交数据版本大 于数据库记录当前版本,数据被更新,数据库记录 version 更新为 2 。

4 操作员 B 完成了操作,也将版本号加一( version=2 )试图向数据库提交数据( balance=$80 ),但此时比对数据库记录版本时发现,
操作员 B提交的 数据版本号为 2 ,数据库记录当前版本也为 2 ,不满足“ 提交版本必须大于记 录当前版本才能执行更新 “ 的乐观锁策略,
因此,操作员 B 的提交被驳回。 这样,就避免了操作员 B 用基于version=1 的旧数据修改的结果覆盖操作员 A 的操作结果的可能。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值