锁的类型以及粒度,两段锁协议,隐式和显示锁
锁的粒度
行级锁 表级锁
应尽量只锁定需要修改的那部分数据,而不是所有资源。锁定的数据量越少,发生锁争用的可能性就越小,并发行就越高。
加锁需要消耗资源,锁的各种操作都会增加系统开销。因此锁的粒度越小,系统开销就越大。
在选择锁的粒度时,需要在锁开销和并发程度之间作一个权衡
锁的类型
1.读写锁
- 排他锁,简写为X锁,又称写锁
- 共享锁,简写为S锁,又称读锁
规定:
- 事务对数据对象A加了X锁,就可以对A进行读取和更新。加了X锁,其他事务就不能再对该数据加锁了
- 事务对数据对象A加了S锁,就可以对A进行读取操作,但不能进行写操作,其他事务可以对A加S锁,但不能加X锁。
即只有S锁和S锁时兼容的
2.意向锁
避免加表锁前逐行确认是否加了锁。逐行确认太过麻烦。
意向锁的作用:
假如事务A想要申请整个表的写锁,那么它需要逐行判断是否有读锁或写锁存在,效率太低。
意向锁就是在加锁前,先对该表加一个意向锁(IX或IS)。这样之后再有事务要申请表的X可以直接判断表上是否有S\X\IX\IS存在,有的话就先阻塞。
意向锁是在原有的X/S锁之上引入IX/IS,IX/IS都是表锁,用来表示一个事务想要在表中的某个数据行上加X锁或S锁。有以下两个规定:
- 一个事务在获得某个数据行对象的S锁之前,必须先获得表的IS锁
- 一个事务在获得某个数据行对象的X锁之前,必须先获得表的IX锁
各种表的兼容关系(能否在有另一个锁的时候加锁):
IX\IS之间两两兼容,X\S之间只有S\S兼容
X和任何锁都不兼容,S锁还和IS锁兼容
综上:只有IS\IX之间,S锁和IS、S之间兼容,其它均不兼容
三级封锁协议
一级封锁协议
事务T要修改数据A必须先加写锁X,写完再释放。由于X锁之间不兼容。
故解决了数据写覆盖的问题。
但不能解决脏读问题
二级封锁协议
在一级封锁协议的基础上,要求读取数据时必须加S锁,读取完马上释放S锁
可以解决脏读问题。事务A不会读到事务B修改了但没提交的可能的脏数据。
三级封锁协议
在二级的基础上,加了S锁,但在事务结束的时候才释放S锁。
解决了不可重复读问题。因为在事务没有释放S锁之前,没有其它事务能够修改该数据
两段锁协议
两段锁协议规定所有的事务应遵守的规则:
① 在对任何数据进行读、写操作之前,首先要申请并获得对该数据的封锁。
② 在释放一个封锁之后,事务不再申请和获得其它任何封锁。
定理:若所有事务均遵守两段锁协议,则这些事务的所有交叉调度都是可串行化的。
充分条件,不是必要条件