MySQL 在高并发下的 订单撮合 系统使用 共享锁 与 排他锁 保证数据一致性

场景描述

高并发的业务常见是有不少种类的,最多见的例如秒杀抢购。它们都有一个共同的特色就是数据更新都比较频繁,一般涉及到多张业务表的增改操做,且表格越多的,要考虑的问题也越多。数据库

订单撮合能够理解为订单买卖,拿这个为例子进行列举一个可能会致使数据错乱的情形。假设如今买卖手机,A用户是要买手机的,B用户是卖手机的。A的买入单订单1,和B的卖出单订单2,订单2卖出手机,一台手机卖1000元。此时A的网上的钱包余额是1001元,恰好比手机价格高,是能够成交的。架构

此时记录用户钱包钱数数量的是一张数据表。每次花费了钱或者增长了钱,都要更新这个表。并发

当这两笔订单进入到系统里面进行撮合。假设系统的订单撮合运行流程以下图所示:高并发

 

 

当判断条件进行A用户的钱包余额判断的时候,发现 1001 > 1000,结果是经过,此时准备进入“进行记录更细”步骤。可是,就在这个过程之中的时间差中,A用户使用了系统的网上提现功能,并成功转出了10元,剩余的是1001 - 10 = 991元。可是因为撮合系统的余额判断过程以及经过了,致使下面的交易流程依然能进行,最终A用991元买了B的1000元售价的手机。性能

解决问题

上述的常见问题是一个很简单的模型,现实的系统中每每是更复杂的。可是它所体现出的问题倒是真实存在的,对于这类问题,有不少解决方案。其中,就能够考虑使用数据库的锁。学习

本文要介绍的是MySQL数据库共享锁排他锁,其它的不做说明或引伸。spa

订单撮合实例

下面的截图就是我所重写好的撮合系统原始的PHP代码,所使用了表锁的方式来解决前面的并发读写致使数据脏乱的问题。这种方式虽然是解决了问题,可是致使了性能低下的问题。code

 

 

共享锁 与 排他锁

前置知识:

  • MySQL 是数据库,不是数据库引擎
  • MySQL有两种经常使用存储引擎: MyISAMInnoDB
  • MyISAM不支持事务操做,InnoDB支持事务操做
  • MySQL 的锁分有 行锁表锁
  • MyISAM 只有表锁
  • Innodb 行锁,表锁都有
  • 行锁中有共享锁排他锁
  • 共享锁 简称 S锁,排他锁简称 X锁

行锁与表锁

简述:索引

  • 行锁,锁的是表中对应的行,只限制当前行的读写。事务

  • 表锁,锁的是整张表,限制的是整张表的数据读写。

比较:

  • 行锁,计算机资源开销大,加锁慢;会出现死锁;锁定粒度最小,锁冲突的几率最低,并发度最高,性能高。
  • 表锁,计算机资源开销小,加锁快;不会出现死锁;锁定粒度大,锁冲突的几率最高,并发度最低,性能低。

两种行锁的特色

共享锁

A 对数据 B 加了 共享锁,A能读取和修改数据B,C 等其它只能读取数据B,可是不能修改。直至A释放了B的锁。

排他锁

A 对数据 B 加了 排他锁,A能读取和修改数据B,C 等其它不能再对数据B加其它的锁。直观体验是不能修改,不能使用含有加锁动做的select读取。

两种行锁的加锁方式

要注意的是:

  • 行锁的实现SQL语句中必需要有索引的限制条件,例如含有 where id=xxx 这类语句。
  • 行锁的实现SQL语句没有索引限制条件会变成表锁
  • InnoDB引擎 默认的修改数据类SQL语句,update,delete,insert等,都会自动给涉及到的数据加上排他锁。

共享锁

  • select 的添加可使用知足格式:select ... where 索引限制 lock in share mode 的语句。例如“select name from lgh_user where id = 1 lock in share model” 此时 id 是索引。

排他锁

  • 知足格式:select ... where 索引限制 for update 的语句

锁的释放

  • 非事务(Transaction) 中,语句执行完毕,便释放锁。

  • 行锁在事务 (Transaction) 中,只有等到当前的事务Transaction 进行了 commit 或 roll back,锁才能释放。

操做例子

演示事务 tx 中的例子,文字解析见图。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

改造代码片断

撮合中的全部表锁替换成了共享锁,运行其它业务读取所锁的行数据,在当前事务的批量操做还没结束以前,不容许修改。

 


感兴趣的能够本身来个人Java架构群,能够获取免费的学习资料,群号:855801563 对Java技术,架构技术感兴趣的同窗,欢迎加群,一块儿学习,相互讨论。

相关文章
相关标签/搜索