共享锁(Shared lock)。 例1:----------------------------------------T1: select * from table (请想象它需要执行1个小时之久,后面的sql语句请都这么想象)T2: update table set column1='hello'过程:T1运行 (加共享锁)T2运行If T1 还没执行完 T2等......else 锁被释放 T2执行endifT2之所以要等,是因为T2在执行update前,试图对table表加一个排他锁,而数据库规定同一资源上不能同时共存共享锁和排他锁。所以T2必须等T1执行完,释放了共享锁,才能加上排他锁,然后才能开始执行update语句。
例2:----------------------------------------T1: select * from tableT2: select * from table这里T2不用等待T1执行完,而是可以马上执行。分析:T1运行,则table被加锁,比如叫lockAT2运行,再对table加一个共享锁,比如叫lockB。两个锁是可以同时存在于同一资源上的(比如同一个表上)。这被称为共享锁与共享锁兼容。这意味着共享锁不阻止其它session同时读资源,但阻止其它session update
例3:----------------------------------------T1: select * from tableT2: select * from tableT3: update table set column1='hello'这次,T2不用等T1运行完就能运行,T3却要等T1和T2都运行完才能运行。因为T3必须等T1和T2的共享锁全部释放才能进行加排他锁然后执行update操作。
例4:(死锁的发生)----------------------------------------T1:begin transelect * from table (holdlock) (holdlock意思是加共享锁,直到事物结束才释放)update table set column1='hello'T2:begin transelect * from table(holdlock)update table set column1='world'假设T1和T2同时达到select,T1对table加共享锁,T2也对加共享锁,当T1的select执行完,准备执行update时,根据锁机制,T1的共享锁需要升级到排他锁才能执行接下来的update.在升级排他锁前,必须等table上的其它共享锁释放,但因为holdlock这样的共享锁只有等事务结束后才释放,所以因为T2的共享锁不释放而导致T1等(等T2释放共享锁,自己好升级成排他锁),同理,也因为T1的共享锁不释放而导致T2等。死锁产生了。---------事务未结束不释放锁,互相再等对方释放锁
例5-----------------------------更新锁(Update lock) 为解决死锁,引入更新锁。---------------------------------------T1:begin transelect * from table(updlock) (加更新锁)update table set column1='hello'T2:begin transelect * from table(updlock)update table set column1='world'更新锁的意思是:“我现在只想读,你们别人也可以读,但我将来可能会做更新操作,我已经获取了从共享锁(用来读)到排他锁(用来更新)的资格”。一个事物只能有一个更新锁获此资格。T1执行select,加更新锁。T2运行,准备加更新锁,但发现已经有一个更新锁在那儿了,只好等。当后来有user3、user4...需要查询table表中的数据时,并不会因为T1的select在执行就被阻塞,照样能查询
例6----------------------------------------------------------T1: select * from table(updlock) (加更新锁)T2: select * from table(updlock) (等待,直到T1释放更新锁,因为同一时间不能在同一资源上有两个更新锁)T3: select * from table (加共享锁,但不用等updlock释放,就可以读)这个例子是说明:共享锁和更新锁可以同时在同一个资源上。这被称为共享锁和更新锁是兼容的
例7----------------------------------------alter table .... (加schema locks,称之为Schema modification (Sch-M) locksDDL语句都会加Sch-M锁该锁不允许任何其它session连接该表。连都连不了这个表了,当然更不用说想对该表执行什么sql语句了。
在只有单一用户的数据库中,用户可以任意修改数据,而无需考虑同时有其他用户正在修改相同的数据。但在一个多用户数据库中,多个并发事 务中包含的语句可能 会修改相同的数据。数据库中并发执行的事务最终应产生有意义且具备一致性的结果。因此在多用户数据库中,对数据并发访问(data concurrency)及数据一致性(data consistency)进行控制是两项极为重要的工作。
1、数据并发访问指多用户同时访问相同的数据。
2、数据一致性指系统中每个用户都能够取得具备一致性的数据,同时还能够看到自己或其他用户所提交的事务对数据的修改。
为了描述同时执行的多个事务如何实现数据一致性,数据库研究人员定义了被称为串行化处理(serializability)的事务隔离 模型(transaction isolation model)。当所有事务都采取串行化的模式执行时,我们可以认为同一时间只有一个事务在运行(串行的),而非并发的。
以串行化模式对事务进行隔离的效果很好,但在此种模式下应用程序的效率将大大降低。将并行执行的事务完全隔离意味着即便当前只存在一个 对表进行查询(query)的事务,其他事务也不能再对此表进行插入(insert)操作了。总之,为了满足实际要求,我们需要在事务的隔离程度与应用的 性能之间找出一个平衡点。
ANSI/ISO SQL 标准(SQL92)定义了四种事务隔离级别(transaction isolation level),这四种隔离级别所能提供的事务处理能力各不相同。这些事务隔离级别是针对三种现象定义的,在并发事务执行时,需要阻止这三种现象 中的一种或多种发生。
三种需要阻止的现象(preventable phenomena)是:
1、脏读取(dirty read):一个事务读取了被其他事务写入但还未提交的数据。
2、不可重复读取(nonrepeatable read):一个事务再次读取其之前曾经读取过的数据时,发现数据已被其他已提交的事务修改或删除。
3、不存在读取(phantom read):事务按照之前的条件重新查询时,返回的结果集中包含其他已提交事务插入的满足条件的新数据。
oracle中针对管理数据并发访问及数据一致性,使用的多种方式中有一种程序代码可以参考的方式:
多版本并发访问控制