数据库知识-锁模块

1.MyISAM与InnoDB关于锁方面的区别是什么

  • MyISAM默认使用的是表级锁,不支持行级锁
  • InnoDB默认用的是行级锁,也支持表级锁

MyISAM引擎

MyISAM引擎在进行查询的时候,会自动为表加上一个读锁,而对数据进行增删改的时候,会为我们操作的表,加上一个表级别的写锁,当读锁没有被释放,另外一个session想要对同一个表加上写锁,他就会被堵塞,直到所有的读锁被释放位置。

如何显示的为表加上读锁,如下:

 释放锁: 

  • 读锁的别名:共享锁 --上了共享锁之后,依然支持上共享锁,但不支持上排它锁
  • 写锁的别名:排它锁--上了排它锁之后,就不支持再上其他的锁

insert、delete、update都会上排它锁,对于select也可以上排它锁,如下:

 当select操作上排它锁之后,其他session中的select也会被堵塞

InnoDB引擎

1.如下模拟两个session对同一行数据进行修改的情况:

两个session的修改语句如下:

执行结果发现,并没有出现第二个session在执行时出现堵塞的情况

InnoDB使用个是二段锁,即加锁和解锁是分两个步骤完成的,即先对同一个事务里的一批操作分别进行加锁,然后到commit的时候,在对事务里加上的锁进行统一的解锁,而当前的commit是自动提交的,所以看起来和MyISAM没哟太大的区别。

我们可以通过执行以下命令得到结论:

on:代表事务默认是自动提交的。

2.关闭自动提交(该设置只针对当前的session,而其他session仍然是自动提交的):

 操作验证如下(前提的首要关闭自动提交):

1:其中一个session加上共享锁,执行如下语句:

2:在另外一个session中对同一行执行update操作

实验结果是第二个session中的操作能修改数据成功。

原因如下:

InnoDB对select进行了改进,不会默认上共享锁,第一个session中的select操作并没有对该行上锁,所以才导致更新是成功的。InnoDB引擎下如何显示的加共享锁,如下:

当在另外一个session中执行update操作的时候就会堵塞。

当sql语句不走索引时,整张表都会被锁住。

在session1中先执行以下sql

在session2中执行以下sql 

 虽然是针对不同行的操作,但由于sql没有走索引,整张表都会被锁住,第二个sql将会被阻塞。

 

 

DML锁:对数据进行操作的锁

DDL锁:对表结构进行改动的锁

 悲观锁:对系统被外界(本系统当前其他事务+来自外部系统事务)修改持悲观态度,因此在数据处理过程中将数据处于锁定状态,依赖于数据库层提供的锁机制。

乐观锁:认为数据一般情况下不会造成冲突,所以在数据进行提交更新时,才会对数据冲突与否进行检测,如果发生冲突,则返回错误信息,让用户决定如何去做。不会使用数据库提供的锁机制。一般就是记录数据版本,使用版本号或者时间戳。

版本号(version字段):每次更新数据时,为了防止冲突,先去检查version再做更新,更新成功的话version+1

2.数据库事务的四大特性

ACID特性

Automic:事务包含的一组操作要么全执行,要么全不执行

Consistency:数据从一个一致性状态到达另一个一致性状态,数据满足完整性约束

Isolation:事务完成前数据的中间状态对其他事务是不可见的

Durabliity:保证提交的事务对数据库影响的永久性,需要REDO日志重启时恢复

3.事务隔离级别以及各级别下的并发访问问题

事务并发访问引起的问题以及如何避免

查看session事务隔离级别:select @@tx_isolation

设置当前session的事务隔离级别:set session transaction isolation level ...

  1. LU(Lost Update丢失更新):一个事物的更新覆盖了另一个事物的更新----现在主流数据库都为为我们自动加锁,mysql所有事务隔离级别在数据库上均可避免此类问题。
  2. DR(Dirty Read读取脏数据):一个事务读取了另一个事务更新却没有提交的数据----在RC(Read Commmited)隔离级别以上均可避免
    set session transaction isolation level read commited

     

  3. NRR(Non-Repeatable Reads不可重复读):一个事务对同一个数据项的多次读取操作可能得到不同的结果,事务A多次读取同一数据,事务B在事务A读取数据的过程中,对数据进行了更新和提交,使得事务A多次读取时,得到的数据不一致----在RR(Repeatable Read)隔离级别以上均可避免,确保在同一事务中,对同一个数据的先后读取的结果是一样的。
    set session transaction isolation level repeatable read

     

  4. (Phantom Reads幻读):事务A读取与搜索条件相匹配的若干行,事务B以插入或删除行等方式来修改事务A的结果集,导致事务A看起来像出现幻觉一样----S(Serializable)隔离级别可以避免
    set session transaction isolation level serializable

 

4.InnoDB可重复读隔离级别下如何避免幻读

  • 表象:快照读(非阻塞读)----伪MVCC
  • 内在:next-key锁(行锁+gap锁)

什么是当前读和快照读

当前读:加了锁的增删改查

快照读:不加锁的增删改查 

 测试:4个session,1和2是RC,3和4是RR

session1和session2同时开启事务后分别执行以下:

 

 在session1中执行快照读的结果

在session1中执行当前读的结果

 结论1:在RC隔离级别下,快照读和当前读的效果一样

在session3和session4中进行同上面一样的操作

在session3中执行快照读的结果

在session4中执行当前读的结果

 结论2:在RR隔离级别下,快照读有可能读到数据的是历史版本,第一次创建快照读的地方很关键,决定了后续快照读取出的数据的版本。

行锁:对单个行上的锁

Gap锁:加载插入数据空隙的锁,防止同一事物的两次当前读出现幻读的情况下

 

5.RC、RR级别下的InnoDB的非阻塞读如何实现

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值