(二)MySQL锁问题---InnoDB(行锁理论)

(一)MySQL锁问题—MyISAM

InnoDB与MyISAM两种存储引擎采用的锁机制是不一样的,MyISAM采用的是表锁,而InnoDB采用的是行锁(确切的说是行锁表锁共同控制)进行控制。MyISAM采用表锁机制,用大白话讲就是当需要进行对表进行读写操作的时候对整张表进行加锁,这样来限制其他端对表的访问;InnoDB采用行锁机制,用大白话讲就是当需要进行对表读写操作的时候,对需要操作的某条记录进行锁定;所以相对于MyISAM直接锁定整张表来控制表的读写来说,InnoDB采用行锁控制的效率要高的多,这也是InnoDB符合当今并发量大的需求,广受欢迎的原因。

 查看数据库默认使用的存储引擎(即在创建表,默认使用的存储引擎)--show  variables like "%table%";

![![在这里插入图片描述](https://img-blog.csdnimg.cn/20181225152711133.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODMxMjcxOQ==,size_16,color_FFFFFF,t_70](https://img-blog.csdnimg.cn/20181225152742668.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODMxMjcxOQ==,size_16,color_FFFFFF,t_70
(注意:如果要进行测试行锁的功能,那么就要创建InnoDB类型的存储引擎,或者修改默认采用的设置)

  • InnoDB与MyISAM的最大不同特点有两点:
    1.支持事务
    2.采用行级锁

  • 什么是事务?
    事务是由一组SQL语句组成的逻辑处理单元,要么都执行成功,要么都不执行成功,否则会破坏数据的完整性。比如张三给李四转账100元,那么需要执行两条语句,一条是张三的扣除100元的SQL,一条是李四的添加100元。比如在不采用事务的情况下,如果张三扣钱成功,李四+100失败,就会导致张三的100元不翼而飞,这样就破坏了数据的完整性。

  • 为什么行锁需要支持事务,而表锁不需要支持事务?
    还是拿转账的问题来说明问题。如果数据库表采用的是MyISAM存储引擎,那么也就是说对表的操作采用的是锁机制是表锁。那么在对表进行修改数据操作的时候,那么就会把整张表锁定,其它读写的会话需要等待,我们只需要将张三账户扣除100,给李四账户+100元,然后进行锁释放即可,不会对数据的完整性破坏。

    但是如果数据库表采用的是InnoDB类型的存储引擎的话,那么也就是说对表的操作采用的是行锁机制。那么在进行对表进行修改操作时,只会对操作的某条记录进行锁定。比如有这样一个需求:不允许某个用户账户的余额大于150。张三账户有100元,李四账户有100元,王五账户有100元,张三和王五同时给李四转账50元,张三执行了一条扣除自己50元的操作,然后王五也执行了一条扣除自己50元的权限,说时迟那时快,王五先抢到了扣除李四50元的写权限,即先获取了行锁,得到了这行的读写权限,执行完后释放行锁。但是张三来进行操作的时候,已经发现不满足条件了,给李四+50元操作失败。所以InnoDB需要支持事务,因为当前会话只能锁定某条记录的读写权限,并不能阻塞其它会话对其它记录行进行读写操作。而表锁就不一样了,只要我获取到了表锁,提前检测李四账户余额是不是达到了150,这里检测是有效的,因为没有其它会话可以操作这张表了,更不要说去修改某条记录的权限了,表锁检测到的数据是不会变的(在释放表锁之前)。张三和王五同时检测到李四账户是100元满足条件,但是李四的数据是随时被其它获得行锁会话改变的。

猜你喜欢

转载自blog.csdn.net/weixin_38312719/article/details/85248487