赞
踩
个人理解,所谓的锁就是为了保证数据库数据操作的一致性而产生的一种机制,即我们可能有很多数据,但是当我们有多个人或者多个线程或会话对同一条数据或同一批数据执行操作时,可能大家都要修改这一部分数据,但为了保证单独一个人的操作在前后都保持一致而不被其他人在自己不知情的情况下中途又修改了数据而导致的与自己预期结果不一致而导致的问题。
MySQL 常用存储引擎的不同锁机制
MyISAM 和MEMORY采用 表级锁(table-level locking)
BDB 采用页面锁(page-level locking)或表级锁,默认为页面锁
InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁
MySQL 默认为 InnoDB 引擎,也就默认是行级锁
共享锁又称读锁:
当一个事务对某几行上读锁时,允许其他事务对这几行进行读操作,但不允许其进行写操作,也不允许其他事务给这几行上排它锁,但允许上读锁。
排它锁又称写锁:
当一个事务对某几个上写锁时,不允许其他事务写但允许读。更不允许其他事务给这几行上任何锁。包括写锁。
insert ,delete , update在事务中都会自动默认加上排它锁
共享锁写法:加 lock in share mode
例如:
SELECT ........ LOCK IN SHARE MODE
共享锁写法:加 for update
例如:
SELECT ........ FOR UPDATE
(表级锁定分为表共享读锁(共享锁)与表独占写锁(排他锁))
如何检测是否是行锁?
开启两个会话,在第一个会话中将事务级别改为不提交,然后读取某个范围内的数据。
然后在第二个会话中访问第一个会话中选中的数据,由于没有提交事务所以应该还是等待,无法执行的结果。
访问第一个会话中指定范围外的数据,如果立即成功说明不是表锁,是行锁,否则就是表锁。
通过show VARIABLES like “%innodb_lock_wait_timeout%” 查询当前mysql设置的锁超时时间,默认50秒。
通过set innodb_lock_wait_timeout = 60; 设置锁的超时时间为60秒。
假设目前我们有二十条数据,第一个事务先锁定了前十条,第二个事务锁定了后十条。
后来第一个事务开始申请访问后十条并锁定,阻碍了后十条的释放,而第二个事务也申请访问前十条并锁定,导致前十条无法释放,从而形成循环导致死锁问题。
间隙锁:在条件查询如:where id > XXX,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)”,间隙的目的是为了防止幻读
意向锁:意向锁分为 (意向共享锁)intention shared lock (IS) 和 (意向排他锁)intention exclusive lock (IX),意向锁的目的是表明有事务正在或者将要锁住某个表中的行
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。