3 mysql锁机制

3.1 锁的定义

锁是计算机协调多个进程或线程并发访问某一资源的机制
表级锁、页面锁、行级锁;
开销、加锁速度、死锁、粒度、并发性能衡量锁的性能 。除了表级锁都会出现死锁情况。
表级锁 锁定粒度最大 发生锁冲突的概率最高

3.2 常见锁

InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁。

3.2.1 获取InnoDB行锁争用情况

mysql> show status like ‘InnoDB_row_lock%’;
±------------------------------±------+
| Variable_name | Value |
±------------------------------±------+
| Innodb_row_lock_current_waits | 0 |
| Innodb_row_lock_time | 0 |
| Innodb_row_lock_time_avg | 0 |
| Innodb_row_lock_time_max | 0 |
| Innodb_row_lock_waits | 0 |
±------------------------------±------+
5 rows in set (0.00 sec)

如果InnoDB_row_lock_waits和InnoDB_row_lock_time_avg的值比较高,表示锁争用情况比较严重。

3.2.2 InnoDB的行锁模式以及加锁方法

InnoDB实现了一下两种类型的行锁:

共享锁(S):允许一个事务去多一行,阻止其它事务获得相同数据集的排他锁。
排他锁(X): 允许获得排他锁的事务更新数据,阻止其它事务获得相同数据集的共享锁和排他写锁

为了允许行锁和表锁共存InnoDB还有两种内部使用的意向锁 都是表锁
意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。
意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。

请求锁模式与当前锁模式

事务的请求锁模式与当前锁模式兼容时才能执行。
使用共享锁模式下,查询完数据后不要进行更新操作,不然又可能会造成死锁;要更新数据,应该使用排他锁模式。

3.2.3 InnoDB行锁实现方式

InnoDB行锁是通过给索引上的索引项加锁来实现的
只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁

访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的

3.2.4 间隙锁

查询范围大于已有记录,innodb会对不存在的记录加锁,导致后面需要插入的数据阻塞,尽量使用相等条件来访问更新数据。

3.3 死锁

3.3.1 死锁定义

两个事务需要获取同一个锁资源。
InnoDB一般都能自动检测到,并使一个事务释放锁并回退,另一个事务获得锁,继续完成事务

外部锁通过设置锁等待超时参数 innodb_lock_wait_timeout来解决.
SHOW GLOBAL VARIABLES LIKE ‘innodb_lock_wait_timeout’;//查看锁等待超时时间
SET GLOBAL innodb_lock_wait_timeout=50;//设置锁等待超时时间

3.3.2 避免死锁的方法

1 在事务中约定以相同的顺序来访问表;
2 并发处理时每个线程按固定的顺序来处理记录;
3 写操作直接申请排他锁;
4 降低隔离级别 从可重复读降低到读已提交 SELECT…FOR UPDATE加排他锁
5 可以直接做插入操作,然后再捕获主键重异常,或者在遇到主键重错误时,总是执行ROLLBACK释放获得的排他锁
当第1个线程提交后,第2个线程会因主键重出错,但虽然这个线程出错了,却会获得一个排他锁!
这时如果有第3个线程又来申请排他锁,也会出现死锁

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值