醋醋百科网

Good Luck To You!

SQL高级:SQL 的并发问题的解决方案-锁机制

目的

锁机制的出现是为了解决资源共享而造成的并发问题。

并发问题包括 4 种:

  • 脏读
  • 幻读
  • 不可重复读
  • 丢失更新

从分类的角度来讲,可以将锁分为 2 类:

  • 读锁,也叫共享锁,可读不可写
  • 写锁,也叫互斥锁,不可读不可写

从操作范围的角度来讲,可以将锁分成 2 类:

  • 表锁
  • 行锁


表锁

是一次性对一张表整体加锁。

共有 6 个特点:

  1. 开销小
  2. 加锁快
  3. 无死锁
  4. 锁的范围大
  5. 容易发生锁冲突
  6. 并发度低
  7. 解锁命令解锁

使用举例:MyISAM 存储引擎使用


行锁

一次性对一条数据加锁。

共 6 个特点:

  1. 开销大
  2. 加锁慢
  3. 容易出现死锁
  4. 锁的范围较小
  5. 不容易发生锁冲突
  6. 并发度高
  7. 事务解锁

使用举例:InnoDB 存储引擎使用


存储引擎共 2 类:

  • MyISAM
  • InnoDB

MyISAM 在执行查询语句前会有 2 步,

  • 会自动给涉及的所有表加读锁,
  • 在执行更新操作前,会自动给涉及的表加写锁

因此,MyISAM 会导致 2 种结果:

  • 对 MyISAM 的读操作,不会阻塞其他进程对同一表的读请求,但会阻塞同一表的写请求。只有当读锁释放后,才会执行其它进程的写操作。
  • 对 MyISAM 的写操作,会阻塞其他进程对同一表的读和写操作,只有当写锁释放后,才会执行其它进程的读写操作。

结论:

立刻获取的资源比较多的时候,使用 InnoDB ; 否则使用 MyISAM 。

分析锁定情况

表锁具体的方法有 2 种:

  • 查看加锁情况 : show open tables
  • 查看表锁定情况的严重程度 : show status like 'table%'

行锁分析的方法:

  • 查看加行锁情况 :show status like '%innodb_row_lock%'

代码实例

实例 1

目的:表锁加读锁的展示

数据准备:




执行增加读锁:


执行后:


实例 2

目的:表锁加写锁的展示

执行后:

实例 3

目的:行锁操作相同的行数据

数据准备:


执行后:

总结:

如果会话 0 对数据 a 进行增删改操作时,则其它会话必须等待会话 0 结束事务 commit 或 rollback 之后,才能对数据 a 进行操作。

需要注意 2 项:

  • 如果没有索引,行锁会自动转成表锁。
  • 如果有 where , 则实际加锁的范围就是 where 后面的范围,不是实际的值。间隙锁会导致在范围内却不存在。


实例 4

目的:行锁操作不同的行数据

执行结果:


各自执行,互不影响。

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言