一、锁的概念和种类
1.排他锁(X锁):排他锁的作用顾名思义就是排他,如果一个变量被一个事务上了排他锁,那么其他事务将不允许对这个变量进行任何的操作,包括读和写。
排他锁可以先上也可以后上,如果一个事务对一个变量先上了排他锁,那么只有等到这个事务被提交或者被撤销,释放了这个排他锁,其他事务才能访问。
后上排他锁,就是指,当这个变量已经有了其他事务的共享锁或者排他锁,本事务再想上排他锁,就必须等待这个变量上没有其他变量的任何锁,注意是:任何锁!!
2.共享锁:共享锁也叫读锁,允许多个事务共享读取同一个变量x,但是不允许同时写。如果想要写就需要上排他锁,然后这就属于后上排他锁的情况,这种情况一般是上不上去的。如果可以上那就是按照顺序升级为排他锁,提交,然后释放锁。
二、简单事务视图和常规事务视图:
简单事务(Simple scheduler):指的是阻止任何可能导致开放事务集不再是数据不相交的操作。
换人话说就是,这个就是对所有的行为上了一把排他锁,不论是读还是写。
例如:
有下列队列:
s1 : r1[z], r3[y], r2[y], c3, w2[z], w2[y], r1[z], c2, r1[x], c1.
TA1首先读了z,读之前TA1给z上了一个排他锁,TA3读了y,并先给y上了排他锁,TA2想要读y,读之前TA2要给y上一个TA2的排他锁,但是y已经有了TA3的排他锁,所以队伍阻塞,等待其他事务的行为,所以s1队列显然不是一个简单事务的逻辑。
常规事务(Common scheduler):阻塞任何使开放事务集不再写分离的操作。
换人话说就是,这个过程对读行为上了共享锁,但是对写行为上了排他锁。
那么我们依然分析上面那个队列:
s1 : r1[z], r3[y], r2[y], c3, w2[z], w2[y], r1[z], c2, r1[x], c1.
我们用更清晰的方法表示这个过程:
TA1 | TA2 | TA3 |
对z上共享锁 成功 事务继续 | ||
读取z | ||
对y上共享锁 成功 事务继续 | ||
读取y | ||
对y上共享锁 成功 事务继续 | ||
读取y | ||
提交 | ||
释放y的共享锁 | ||
对z加排他锁,由于z有TA1的共享锁,排他锁失败,事务阻塞,等待z释放锁 | ||
等待 | ||
等待 | ||
对z上共享锁,成功,事务继续 | 等待 | |
读取z | 等待 | |
对x上共享锁,成功,事务继续 | 等待 | |
读取x | 等待 | |
提交 | 等待 | |
释放x的共享锁,z的共享锁 | 等待 | |
对z加排他锁,成功,事务继续 | ||
写z | ||
对y升级为排他锁,成功,事务继续 | ||
写y | ||
提交 | ||
释放z的排他锁,y的排他锁 |
所以我们发现,按照执行顺序,s1显然也不是常规事务调度方式。