一、数据库当中的锁
数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。
加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。
在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两种基本的锁类型来对数据库的事务进行并发控制。
锁的类型有三种:
共享(S)锁:多个事务可封锁一个共享页;任何事务都不能修改该页; 通常是该页被读取完毕,S锁立即被释放。
排它(X)锁:仅允许一个事务封锁此页;其他任何事务必须等到X锁被释放才能对该页进行访问;X锁一直到事务结束才能被释放。
更新(U)锁:用来预定要对此页施加X锁,它允许其他事务读,但不允许再施加U锁或X锁;当被读取的页将要被更新时,则升级为X锁;U锁一直到事务结束时才能被释放。
为什么要使用U锁?
主要是为了避免共享锁所造成的死锁问题。在数据库当中,排它锁,也就是修改锁,在加锁的之前,需要先获得共享锁,将数据读出之后,再将共享锁升级为排它锁,但是排它锁和共享锁是不能兼容的。如果,这是有多个事务对其加了共享锁,并且都想升级为排它锁,那么就会造成相互等待的情况,从而造成死锁。使用U锁,可以避免这种情况的发生。在申请排它锁之前,需要首先申请U锁,U锁只能有一个,并且在事务结束时才会释放,从而导致只有一个事务在申请了U锁,并且后面也是只有一个事务先申请共享锁,并升级为修改所,这时不会有死锁
申请U锁
申请S锁
申请X锁
释放X锁
释放S锁
释放U锁
之后才会有另一个事务再来重复上面的过程
申请U锁
申请S锁
申请X锁
释放X锁
释放S锁
释放U锁
这样他们之间是串行的,不会有死锁现象发生。
二、数据库当中的冲突
- 四大冲突问题
- 脏读:事务A
修改了某个数据,然后事务B读取了修改的数据,但是后来A回滚了,导致事务B都得数据是错误的 - 不可重复读:事务A要读取两次数据,但是在两次读之间事务B修改了数据,导致两次读的数据不一样
- Fsdf幻读:事务A修改了一个表的所有数据,在这同时事务B向其中插入了一行数据,事务A处理完之后,会发现里面还有没有修改的行。
这是可以限制事务B在A完成之前不要进行,就可以
http://www.cnblogs.com/happyframework/p/3435069.html
http://www.cnblogs.com/phoebus0501/archive/2011/02/28/1966709.html