Discussed in oracle locking mechanism
库用两种类型的锁,一种是共享锁,另一种是排他锁。在像表或是表中一行只能获得一个排他锁,但是共享锁可以再单个的资源中被多次获得。
锁影响读和写相互作用。下面的一些规则综述了oracle数据库关于读和写的一些行为:
1)仅当被写操作编辑时一行记录会被锁定
当一条更新的命令更新一行是,这个事务就会只获得这一行的锁。通过锁定在表中的这一条数据层次面,这个数据库会很小的争夺对这个共享数据来说。正常情况下,数据库不会逐渐升级为对这个块的行锁或是到一个表锁的等级。
2)只能在同一时间对一个数据块进行写入:
如果一个事务编辑表中的一行记录,那么这个行锁就会阻止其他事务同时对同一行的元组进行编辑。
3)读永远不会妨碍写
因为读一行数据不会进行对它枷锁,另一个事务可以同时对同一行进行编辑。这个当然除了select 。。。from update这个语句之外,这个select是一个很特别的语句不会在它读的时候锁住一行数据。
4)写的时候不影响读
当一行数据被写入改变的时候,这个数据库会使用undo date去提供读取一致的行数据。
三)锁的使用
在一个单用户数据库中,锁就不需要了因为只有一个用户去编辑信息。然而,当多用户去访问和编辑数据时,这个数据库必须提供一种方式去阻止去并发的编辑相同的数据。锁机制达到下面非常重要的数据库的一些要求:
1)一致性
一个数据的session必须可见和改变数据但是不能被其他的session进行改变数据直到这个用户完成了操作。
2)完整性
在正确修改序列时这个数据和数据结构必须反映所有操作的改变
在事务通过它们锁机制中oracle数据库提供了数据的并发性、一致性、完整性。锁是自动执行的不需要用户操作。
当并发更新一行的时候,会说明需要什么要的锁。在下面的例子中,一个简单的web应用显示最终用户的雇员邮箱和电话号码。这个应用使用update语句像下面这样编辑数据:
eg:
update employees
set email=? ,phone_number=?
where employee_id=?
and email=?
and phone_number=?
在update语句执行前,这个邮箱和电话号码值都是where字句之前的,没有对指定employee编辑之前的值。这个update确保这行记录在被应用最后读和显示给用户不会改变。通过这个方式,这个应用避免失去update数据的问题,当一个用户查看时却别其他用户编辑了.(也就是说不会出现脏读的情况)。
当执行sql语句的时候oracle数据库会自动获得所需要的锁。例如,当一个数据库允许一个会话去编辑一个数据,这个会话必须首先锁定这个数据。这个锁能够给这个session排斥其他的事务对这个数据进行锁定并修改,直到这个锁被释放掉。
因为这个锁的机制,数据库被事务控制联系紧密,应用开发者都会需要定义一些事务的特性,然后数据库会自动的管理锁机制。用户从来不需要锁定许多明确的资源,当然了oracle数据库也允许用户手动去锁定一些资源。
四)锁的模式
oracle数据自动使用最底的锁应用等级限制去最大程度上提供更高的并发性和数据的性。限制越低,就能更好的提供数据被其他用户所访问。相反越高的限制等级就会限制其他用户事务获取他们所需要的数据。
oracle数据库在多用户数据库中使用两中类型的锁(数据库可以使用startup restrict命令启动到一个特权模式下,在该模式下只用特定权限的用户才可以访问数据库)
1)排他锁模式
在这种模式下阻止数据被共享。当一个事务编辑数据的时候就会获得一个排他锁。第一个事务锁定了一个这个数据,那么只有他可以进行修改,其他用户如需在修改这个数据,那么必须等第一个事务修改完成释放了排他锁。
2)共享锁模式
这个模式基于操作有关信息允许这个资源被共享。多个用户读取数据的时候会共享这个数据,持有共享锁去一个需要获得排他锁的用户并发访问。几个事务能够在相同的数据资源中取得共享锁。
假设一个事务使用select 。。。for update 语句去选择单表的一行。那么这个事务会获得一个行级共享排他锁。这个行锁允许其他的会话修改一些其他行,在这个表锁定的时候阻止会话去修改这个数据的结构。因此数据库提供了很多语句去执行。
五)锁的转化和升级 当必要时,oracle会执行锁的转化操作。在锁的转化中,oracle会自动的转换一个表锁从较低的限制到一个较高的限制。 例如。假设一个事务对employee表执行一个select 。。。for update然后更新锁住的行。在这种情况下数据库会自动转换从一个表的行级共享锁到一个表的行级排他锁。在这个事务中这个事务获得行级排他锁来完成所有数据行的插入、更新或是删除操作。因为行锁获取的是最高的约束程度,因此没有其他锁的转化被获得或是去执行。 锁的转化与锁的升级是不同的,锁的转化在许多锁从一个很低的粒度到一个很高的粒度重现。如果一个用户在一个表中锁定了很多的行,然后一下数据库自动的升级这个行锁到一个这个行所属表锁。那么锁的数量会变小,但是约束的程度会增大。 oracle数据库从来都不会升级锁。锁的升级很大程度上会发生思锁。建设一个系统试着为了事务1升级锁是不可行的因为这个锁被事务2持有了。这时当事务2也请求同意个数据被升级一个锁的时候死锁就产生了。 六)锁的持续 当像一个事务不在需要这个资源这种事件发生的时候,oracle数据库会自动的释放锁。在大多数情况下,在事务持续期间oracle数据库会通过事务的语句持有相应的锁。这些锁阻止并发事务的相互干啥,如可能产生的脏读、不可重复读、和幻想读情况。 注意: