Oracle

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

深入浅出oracle锁---原理篇在现代的多用户多任务系统中,必然会出现多个用户同时访问共享的某个对象,这个对象可能是表,行,或者内存结构,为了解决多个用户并发性访问带来的数据的安全性,完整性及一致性问题,必须要有一种机制,来使对这些共享资源的并发性访问串行化,oracle中的锁就可以提供这样的功能,当事务在对某个对象进行操作前,先向系统发出请求,对其加相应的锁,加锁后该事务就对该数据对象有了一定的控制权限,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作(可以做select动作,但select利用的是undo中的前镜像数据了).Oracle锁的分类Oracle锁基本上可以分为二类a:共享锁(sharelocks)也称读锁,s锁b:排它锁(exclusivelocks)也称写锁,x锁在数据库中有两种基本的锁类型:排它锁(ExclusiveLocks,即X锁)和共享锁(ShareLocks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两种基本的锁类型来对数据库的事务进行并发控制。按锁保护的内容分类oracle提供多粒度封锁机制,按保护对象来分,据此又可以分为a:dml锁,datalocks数据锁,用来保护数据的完整性和一致性b:ddl锁,dictionarylocks字典锁,用来保护数据对象的结构,如table,index的定义c:内部锁和闩internallocksandlatchs用来保护数据库内部结构,如sga内存结构dml锁DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁,TM锁的种类有S,X,SR,SX,SRX五种,TX锁称为事务锁或行级锁。当Oracle执行delete,update,insert,selectforupdateDML语句时,oracle首先自动在所要操作的表上申请TM类型的锁。当TM锁获得后,再自动申请TX类型的锁,并将实际锁定的数据行的锁标志位(lb即lockbytes)进行置位。在记录被某一会话锁定后,其他需要访问被锁定对象的会话会按先进先出的方式等待锁的释放,对于select操作而言,并不需要任何锁,所以即使记录被锁定,select语句依然可以执行,实际上,在此情况下,oracle是用到undo的内容进行一致性读来实现的。在Oracle数据库中,当一个事务首次发起一个DML语句时就获得一个TX锁,该锁保持到事务被提交或回滚。在数据行上只有X锁(排他锁),就是说TX锁只能是排他锁,在记录行上设置共享锁没有意义。当两个或多个会话在表的同一条记录上执行DML语句时,第一个会话在该条记录上加锁,其他的会话处于等待状态。当第一个会话提交后,TX锁被释放,其他会话才可以加锁。在数据表上,oracle默认是共享锁,在执行dml语句的时候,oracle会先申请对象上的共享锁,防止其他会话在这个对象上做ddl语句,成功申请表上的共享锁后,再在受影响的记录上加排它所,防止其他会话对这些做修改动作。这样在事务加锁前检查TX锁相容性时就不用再逐行检查锁标志,而只需检查TM锁模式的相容性即可,大大提高了系统的效率。TM锁包括了SS、SX、S、X等多种模式,在数据库中用0-6来表示。不同的SQL操作产生不同类型的TM锁。如表1所示。锁模式锁描述解释SQL操作0none1NULLNULLselect2SS(Row-S)行级共享锁其他对象只能查询这些数据行Selectforupdate、Lockforupdate、Lockrowshare3SX(Row-X)行级排它锁在提交前不允许做DML操作Insert、Update、Delete、Lockrowshare4S(Share)共享锁Createindex、Lockshare5SSX(S/Row-X)共享行级排它锁Locksharerowexclusive6X(Exclusive)排它锁Altertable、Dropable、Dropindex、Truncatetable、Lockexclusive行级排他锁(RowExclusive,简称RX锁)当我们进行DML时会自动在被更新的表上添加RX锁,或者也可以通过执行lock命令显式的在表上添加RX锁。在该锁定模式下,允许其他的事务通过DML语句修改相同表里的其他数据行,或通过lock命令对相同表添加RX锁定,但是不允许其他事务对相同的表添加排他锁(X锁)。行级共享锁(RowShared,简称RS锁)通常是通过select…fromforupdate语句添加的,同时该方法也是我们用来手工锁定某些记录的主要方法。比如,当我们在查询某些记录的过程中,不希望其他用户对查询的记录进行更新操作,则可以发出这样的语句。当数据使用完毕以后,直接发出rollback命令将锁定解除。当表上添加了RS锁定以后,不允许其他事务对相同的表添加排他锁,但是允许其他的事务通过DML语句或lock命令锁定相同表里的其他数据行。共享锁(Share,简称S锁)通过locktableinsharemode命令添加该S锁。在该锁定模式下,不允许任何用户更新表。但是允许其他用户发出select…fromforupdate命令对表添加RS锁。排他锁(Exclusive,简称X锁)通过locktableinexclusivemode命令添加X锁。在该锁定模式下,其他用户不能对表进行任何的DML和DDL操作,该表上只能进行查询。共享行级排他锁(ShareRowExclusive,简称SRX锁)通过locktableinsharerowexclusivemode命令添加SRX锁。该锁定模式比行级排他锁和共享锁的级别都要高,这时不能对相同的表进行DML操作,也不能添加共享锁。######################################################################数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。在数据库中有两种基本的锁类型:排它锁(ExclusiveLocks,即X锁)和共享锁(ShareLocks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两种基本的锁类型来对数据库的事务进行并发控制。Oracle数据库的锁类型根据保护的对象不同,Oracle数据库锁可以分为以下几大类:DML锁(datalocks,数据锁),用于保护数据的完整性;DDL锁(dictionarylocks,字典锁),用于保护数据库对象的结构,如表、索引等的结构定义;内部锁和闩(internallocksandlatches),保护数据库的内部结构。DML锁的目的在于保证并发情况下的数据完整性,。在Oracle数据库中,DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为事务锁或行级锁。当Oracle执行DML语句时,系统自动在所要操作的表上申请TM类型的锁。当TM锁获得后,系统再自动申请TX类型的锁,并将实际锁定的数据行的锁标志位进行置位。这样在事务加锁前检查TX锁相容性时就不用再逐行检查锁标志,而只需检查TM锁模式的相容性即可,大大提高了系统的效率。TM锁包括了SS、SX、S、X等多种模式,在数据库中用0-6来表示。不同的SQL操作产生不同类型的TM锁。在数据行上只有X锁(排他锁)。在Oracle数据库中,当一个事务首次发起一个DML语句时就获得一个TX锁,该锁保持到事务被提交或回滚。当两个或多个会话在表的同一条记录上执行DML语句时,第一个会话在该条记录上加锁,其他的会话处于等待状态。当第一个会话提交后,TX锁被释放,其他会话才可以加锁。当Oracle数据库发生TX锁等待时,如果不及时处理常常会引起Oracle数据库挂起,或导致死锁的发生,产生ORA-60的错误。这些现象都会对实际应用产生极大的危害,如长时间未响应,大量事务失败等。悲观封锁和乐观封锁一、悲观封锁锁在用户修改之前就发挥作用:Select..forupdate(nowait)Select*fromtab1forupdate用户发出这条命令之后,oracle将会对返回集中的数据建立行级封锁,以防止其他用户的修改。如果此时其他用户对上面返回结果集的数据进行dml或ddl操作都会返回一个错误信息或发生阻塞。1:对返回结果集进行update或delete操作会发生阻塞。2:对该表进行ddl操作将会报:Ora-00054:resourcebusyandacquirewithnowaitspecified.原因分析此时Oracle已经对返回的结果集上加了排它的行级锁,所有其他对这些数据进行的修改或删除操作都必须等待这个锁的释放,产生的外在现象就是其他的操作将发生阻塞,这个这个操作commit或rollback.同样这个查询的事务将会对该表加表级锁,不允许对该表的任何ddl操作,否则将会报出ora-00054错误::resourcebusyandacquirewithnowaitspecified.二、乐观封锁乐观的认为数据在select出来到update进取并提交的这段时间数据不会被更改。这里面有一种潜在的危险就是由于被选出的结果集并没有被锁定,是存在一种可能被其他用户更改的可能。因此Oracle仍然建议是用悲观封锁,因为这样会更安全。阻塞定义:当一个会话保持另一个会话正在请求的资源上的锁定时,就会发生阻塞。被阻塞的会话将一直挂起,直到持有锁的会话放弃锁定的资源为止。4个常见的dml语句会产生阻塞INSERTUPDATEDELETESELECT…FORUPDATEINSERTInsert发生阻塞的唯一情况就是用户拥有一个建有主键约束的表。当2个的会话同时试图向表中插入相同的数据时,其中的一个会话将被阻塞,直到另外一个会话提交或会滚。一个会话提交时,另一个会话将收到主键重复的错误。回滚时,被阻塞的会话将继续执行。UPDATE和DELETE当执行Update和delete操作的数据行已经被另外的会话锁定时,将会发生阻塞,直到另一个会话提交或会滚。Select…forupdate当一个用户发出select..forupdate的错作准备对返回的结果集进行修改时,如果结果集已经被另一个会话锁定,就是发生阻塞。需要等另一个会话结束之后才可继续执行。可以通过发出select…forupdatenowait的语句来避免发生阻塞,如果资源已经被另一个会话锁定,则会返回以下错误:Ora-00054:resourcebusyandacquirewithnowaitspecified.死锁-deadlock定义:当两个用户希望持有对方的资源时就会发生死锁.即两个用户互相等待对方释放资源时,oracle认定为产生了死锁,在这种情况下,将以牺牲一个用户作为代价,另一个用户继续执行,牺牲的用户的事务将回滚.例子:1:用户1对A表进行Update,没有提交。2:用户2对B表进行Update,没有提交。此时双反不存在资源共享的问题。3:如果用户2此时对A表作update,则会发生阻塞,需要等到用户一的事物结束。4:如果此时用户1又对B表作update,则产生死锁。此时Oracle会选择其中一个用户进行会滚,使另一个用户继续执行操作。起因:Oracle的死锁问题实际上很少见,如果发生,基本上都是不正确的程序设计造成的,经过调整后,基本上都会避免死锁的发生。#############################################################

1 / 8
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功