并发操作带来的问题
-
丢失修改:两个业务对同一个数据进行修改,导致事务A对数据库的修改被事务B的修改所覆盖。
-
不可重复读:事务对同一数据进行两次读取的结果不同。原因是两次读取的间隙数据被另一个事务修改了
-
读脏数据:事务读取了其他事务修改的数据,但是这个修改后来又被撤销了,这个数据就是被其他事务丢弃的数据
并发调度的可串行性(*)
-
多个事务的并发执行是正确的,当且仅当其结果与某一次串行执行的结果一致,称这种调度为可串行化调度
-
可串行性是并发事务正确性的准则。即一个并发调度,当且仅当它是可串行化的才认为是正确调度
并发控制技术
并发事务如果对数据读写时不加以控制,会破坏事务的隔离性和一致性。为了保持事务的隔离性,系统必须对事务之间的相互作用加以控制,最典型的方式就是加锁。
-
排它锁(Exclusive Locks, 简称X锁):也称为写锁,用于对数据进行写操作时进行锁定。如果事务T对数据A加上X锁后,就只允许事务T对数据A进行读取和修改,其他事务对数据A不能再加任何锁,也不能读取和修改数据A,直到事务T释放A上的锁。
-
共享锁(Share Locks, 简称S锁):也称为读锁,用于对数据进行读操作时进行锁定。如果事务T对数据A加上了S锁后,事务T就只能读数据A但不可以修改,其他事务可以再对数据A加S锁来读取,只要数据A上有了S锁,任何事务都只能再对其加S锁读取而不能加X锁修改。
封锁协议
-
一级封锁协议:是指事务T在修改数据A之前必须先对其加X锁,直到事务结束才释放X锁。解决了丢失修改的问题。
-
二级封锁协议:是一级封锁协议加上事务T在读取数据A之前必须对其加上S锁,读完后即可释放S锁。解决了读脏数据的问题。
-
三级封锁协议:是一级封锁协议加上事务T在读取数据A之前必须对其加上S锁,直到事务结束才释放S锁。解决了不可重复读的问题。
两段锁协议(**)
两段锁协议(2PL):是指同一事务对任何数据进行读写之前必须对该数据加锁;在释放一个封锁之后,该事务不再申请和获得任何其他封锁。(一个事物申请锁的时候,必须全部申请下来。释放锁的时候也必须全部释放。不能先申请一个锁释放一个锁,然后继续申请释放)
‘两段’ 含义:事务分为两个阶段。第一阶段是获得封锁,也称为扩展阶段。第二阶段是释放封锁,也称为收缩阶段
如果遵循两段锁协议,一定是可串行化的;
不遵循两段锁协议,可能是可串行化的,也可能不是;
注: 采用两段锁协议也有可能产生死锁,这是因为每个事务都不能及时解除被封锁的数据,可能会导致多个事务都要求对方已经封锁的数据而不能继续运行。