@[TOC](乐观锁(Optimistic Lock)和悲观锁(Pessimistic Lock))
乐观锁?
顾名思义是比较乐观的,比较相信真善美,每次去读数据,都认为其他事务没有写数据,所以就不上锁,快乐的读取数据,而只有在提交数据的时候进行判断其他事务是否操作过这个数据,如果操作过就回滚(rollback),乐观送其实就相当于检测冲突的手段,可通过记录添加版本或者添加时间戳来实现
悲观锁?
对其他事务都保持怀疑的态度,每次去读取数据都认为其他事务想要去搞事情,所以每次去读数据都会上锁,直到取出数据,悲观锁大多情况下依靠数据库的锁来实现,以保证操上最大程度是独占的,但是随之而来的是各种开销,悲观锁相当于是避免冲突的手段
选择标准:如果并发量不大,或者数据冲突后果不严重,可以使用乐观锁,如果并发量大,数据冲突后比较严重,那么就选择悲观锁
分共享锁(S锁,Shared Lock)和排他锁(X锁,Exclusive Lock)?
从读写的角度,分共享锁(S锁,Shared Lock),和排他锁(X锁,Exclusive Lock),也叫读锁(Read Lock)和写锁(Write Lock),
- 简单理解为
持有分共享锁的事务只读不可写,如果事务A对数据D加上锁后,其它事务只能对D加上S锁而不能加X锁。
持有排他锁X锁的事务可读可写,如果事务A对数据D加上X锁后,其它事务不能再对D加锁,直到A对D的锁解除。
表级锁(Table Lock)和行级锁(Row Lock)?
- 从锁的粒度角度,主要分为表级锁(Table Lock)和行级锁(Row Lock)。
表级锁将整个表加锁,性能开销最小,用户可以同时进行读操作。当一个用户对表进行写操作时,用户可以获得一个写锁,写锁禁止其他的用户读写操作。写锁比读锁的优先级更高,即使有读操作已排在队列中,一个被申请的写锁仍可以排在所队列的前列。
行级锁仅对指定的记录进行加锁
这样其它进程可以对同一个表中的其它记录进行读写操作。行级锁粒度最小,开销大,能够支持高并发,可能会出现死锁。
MySQL的MyISAM引擎使用表级锁,而InnoDB支持表级锁和行级锁,默认是行级锁,还有BDB引擎使用页级锁,即一次锁定一组记录,并发性介于行级锁和表级锁之间。
三级锁协议
三集加锁协议是为了保证事务的并发操作,数据库在读写数据库对象是需要遵循加锁原则的
一级加锁协议:事务T在修改数据R之前必须对它加X锁,直到事务结束方可释放,而若事务T只是读数据,不进行修改,则不需加锁,因此一级加锁协议下可能会出现脏读和不可重复读
二级加锁协议:在一级加锁协议的基础上,加上这样一条规则事务T在读取数据R之前必须对它加S锁,直到读取完毕以后释放。二级加锁协议下可能会出现不可重复读。
三加锁协议:在一级加锁协议的基础上,加上这样一条规则——事务T在读取数据R之前必须对它加S锁,直到事务结束方可释放。三级加锁协议避免了脏读和不可重复读的问题