经常听到数据库的锁机制,不同的数据库的不同实现不同, 听多了就头疼了,今天就把MySQL的锁整的明明白白:
锁
首先想一下为什么我们会需要锁,其实就是为了解决并发操作数据的,是一种控制并发的机制。
乐观锁和悲观锁
乐观锁和悲观锁其实是两种思想,用来指导实现锁的功能的不同实现思想,
- 乐观锁是一种思想,它其实并不是一种真正的『锁』,它会先尝试对资源进行修改,在写回时判断资源是否进行了改变,如果没有发生改变就会写回,否则就会进行重试,在整个的执行过程中其实都没有对数据库进行加锁;
- 悲观锁就是一种真正的锁了,它会在获取资源前对资源进行加锁,确保同一时刻只有有限的线程能够访问该资源,其他想要尝试获取资源的操作都会进入等待状态,直到该线程完成了对资源的操作并且释放了锁后,其他线程才能重新操作资源;
在这两种指导思想下产生了对应的锁:
乐观锁的实现
我们可以对一行数据创建一个字段专门用来存放对这行数据操作时的时间戳,比如我们第一次读取的时候拿到时间戳 timestamep=111,a=2, id =1 ,然后提交a=3更新的时候,我们的update tablename set a = 3 where id =1 timestamp=111 失败,说明这条数据被别的事务操作了。
乐观锁是一种软并发控制,需要你设置好完整的逻辑处理。
悲观锁的实现
悲观锁也就是我们经常说的锁的概念,包括什么共享锁,互斥锁,读锁,写锁,意向共享锁,意向互斥锁,共享锁和读锁是一个概念,互斥锁和写锁一个概念,以此类推 意向共享锁也可以叫意向读锁, 意向互斥锁也可以叫意向写锁。
这些锁的使用使用在哪里是有锁的使用范围的,也就是每种锁的粒度。MySQL的锁的粒度和引擎相关,我们今天就着重介绍一下InnoDB,因为这个是5.5.8版本以后的默认版本。
注意:MySQL的引擎是表级别的,就是在创建表的时候指定,也就是说你一个数据库的不同表你可以指定不同引擎
- MySQL的锁的粒度有:行级锁 和 表级锁。
- MySQL的锁的作用:共享锁(读锁) 和 互斥锁(写锁)---------行级锁。
- MySQL的意向锁是表级锁,
意向锁
- 意向共享锁:事务想要在获得表中某些记录的共享锁,需要在表上先加意向共享锁;
- 意向互斥锁:事务想要在获得表中某些记录的互斥锁,需要在表上先加意向互斥锁;
意向锁其实不会阻塞全表扫描之外的任何请求,它们的主要目的是为了表示是否有人请求锁定表中的某一行数据。
有的人可能会对意向锁的目的并不是完全的理解,我们在这里可以举一个例子:如果没有意向锁,当已经有人使用行锁对表中的某一行进行修改时,如果另外一个请求要对全表进行修改,那么就需要对所有的行是否被锁定进行扫描,在这种情况下,效率是非常低的;不过,在引入意向锁之后,当有人使用行锁对表中的某一行进行修改之前,会先为表添加意向互斥锁(IX),再为行记录添加互斥锁(X),在这时如果有人尝试对全表进行修改就不需要判断表中的每一行数据是否被加锁了,只需要通过等待意向互斥锁被释放就可以了。
各种锁之间的约束关系: