oracle如何锁定行 oracle行锁会自动释放嘛

ORACLE行锁问题

这种情况叫死锁,与网络质量无关。

让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:域名注册、虚拟空间、营销软件、网站建设、临湘网站维护、网站推广。

最大的可能就是程序的原因。

如A进程修改a表的某条记录,修改完a表后,会继续修改b表的某条记录,然后提交事务。

这个时候,B进程在修改b表的那条记录,修改完后要去修改a表的那条记录,然后提交事务。

这样,当A修改完a尚未修改b,B修改完b尚未修改a的时候,就可能出现B进程等待A进程提交事务,A进程又在等待B进程提交事务,两个进程一直在等。

所以死锁就出现了。

Oracle中的锁

这些是基础,必须掌握:锁定的概念:锁定是数据库用来控制共享资源并发布访问的机制。在多用户环境下,多个用户可同时访问相同的数据。Oracle 提供锁以确保在多用户环境下数据的完整性和一致性。在提交或回滚事务之前,Oracle 会锁定正被修改的数据。在用户完成或回滚事务之后,锁会自动释放。只有在提交或回滚事物之后,其他用户才可以更新这些数据。锁的两种级别为:行级锁和表级锁。行级锁主要用于特定的行,表级锁主要用于整个表,下面我就行级锁和表级锁来个说明:行级锁行级锁只对用户正在访问的行进行锁定。如果该用户正在修改某行,那么其他用户就可以更新同一表中该行之外的数据。例如:如果用户1正在更新Jobs 表中的第一行,则用户2可以同时修改该表中的第二行。也就是说除了该表中的第一行,其他用户可以修改任意行,但是第一行的数据其他用户只能select。行级锁是一种排他锁,防止其他事务修改此行,但是不会阻止读取此行的操作。在使用INSERT、UPDATE、DELETE 和SELECT…FOR UPDATE 等 语句时,Oracle 会自动应用行级锁锁定。SELECT...FOR UPDATE 语句允许用户每次选择多行记录进行更新,这些记录会被锁定,且只能由发起查询的用户进行编辑。只有在回滚或提交事务之后,锁定才会释放,其他用户才可以编辑这些记录。SELECT...FOR UPDATE 语句的语法如下: SELECT ... FOR UPDATE [OF column_list][WAIT n|NOWAIT];其中:OF 子句用于指定即将更新的列,即锁定行上的特定列。WAIT 子句指定等待其他用户释放锁的秒数,防止无限期的等待。“使用FOR UPDATE WAIT”子句的优点如下:⒈防止无限期地等待被锁定的行;⒉允许应用程序中对锁的等待时间进行更多的控制。⒊对于交互式应用程序非常有用,因为这些用户不能等待不确定举例:比如一个用户在SQL PLUS下输入这条语句:SQLSELECT * FROM order_master WHERE vencode='V002' FOR UPDATE;此时再开启一个SQL PLUS,以相同的用户登陆,执行下面的命令。SQL SELECT * FROM order_master WHERE vencode='V02' FOR UPDATE WAIT 5;由于要更新的行已经被锁定,上述命令在等待5秒钟之后返回,并给出如下的错误信息:ERROR 位于第1行;ORA-30006;资源已被占用;执行操作时出现WAIT超时。PS:再开启的SQL PLUS 是以相同用户登陆的,用其他用户登陆更是不可能。表级锁表级锁被锁定的表,暂时放在内存中,不提交不进去数据库,也就是说,多个用户在同一时间,同时修改同一个表的同一行时,同时点提交,但是还是按随机的先后被提交进数据库,而不是同时被提交,而是先随机存储后,被再次提交的覆盖。表级锁将保护表数据,在事务处理过程中,表级锁会限制对整个表的访问。可以使用LOCK TABLE 语句显示地锁定表。表级锁用来限制对表执行添加、更新和删除等修改操作。锁定表的语法如下:LOCK TABLE table_name IN lock_mode MODE [NOWAIT];其中:lock_mode 是锁定的模式。NOWAIT 关键字用于防止无限期的等待其他用户释放锁。表级锁的模式包括以下内容:行共享 (ROW SHARE, RS): 允许其他用户访问和锁定该表,但是禁止排他锁定整个表。行共享锁锁定后,在同一时刻,不同用户可以对同一个表中的被行共享锁锁定后的该行,具备增、删、改、查的功能。行排他(ROW EXCLUSIVE, RX):与行共享模式相同,同时禁止其他用户在此表上使用共享锁。使用SELECT...FOR UPDATE 语句会在表上自动应用排他锁。被行排他后,其他用户不能同时修改该行,但是可以插入行,可以查询该行,其他用户也不能再在该表上对此行进行排他。共享(SHARE, S):共享锁将锁定表,仅允许其他用户查询表中的行,但不允许插入、更新或删除行。多个用户可以同时在同一个表中放置共享锁,即允许资源共享,因此得名“共享锁”。例如,如果用户每天都需要在结帐时更新日销售表,则可以在更改该表时使用共享锁以确保数据的一致性。也就是说该表只能查,其他用户想修改表中行的数据,只需要对该表进行共享锁。共享行排他(SHARE ROW EXCLUSIVE , SPX):执行比共享表更多的限制。防止其他事务在表上应用共享锁、共享行排他锁以及排他锁。共享行排他是除了该行以外的其他行也不能增、删、改。只能在此表中加低级表。要是想在该表中更改其他行的数据,就只有其他用户对该行进行共享行排他锁,也仅仅只能修改被这个用户锁定的行,而其他的行也修改不了。排他(EXCLUSIVE,E):对表执行最大限制。除了允许其他用户查询该表的记录,排他锁防止其他事务对表做任何更改或在表上应用任何类型的锁。这个锁应该叫锁中之王,他锁住了的话,其他用户就只有查询的功能了,就别想在该表中干别的事了。BTW:在能加很多锁的表中,如果第一个用户对该表锁定时,没有使用“NOWAIT”语句,是需要第一个用户对该表COMMIT或ROLLBACK 命令释放锁定后,其他用户才能对该表进行锁定。如果其他用户违反了该条,就会无期限的等待。。。。SQL LOCK TABLE order_mater IN SHARE MODE;而使用下面的语句就可以很少的预防这种情况的存在:SQL LOCK TBALE order_mater IN SHARE MODE NOWAIT;这是些扩展的内容,供大家参考

1 引言—数据库锁的基本概念 为了确保并发用户在存取同一数据库对象时的正确性(即无丢失修改、可重复读、不读“脏”数据),数据库中引入了锁机制。基本的锁类型有两种:排它锁(Exclusive locks记为X锁)和共享锁(Share locks记为S锁)。 排它锁:若事务T对数据D加X锁,则其它任何事务都不能再对D加任何类型的锁,直至T释放D上的X锁;一般要求在修改数据前要向该数据加排它锁,所以排它锁又称为写锁。 共享锁:若事务T对数据D加S锁,则其它事务只能对D加S锁,而不能加X锁,直至T释放D上的S锁;一般要求在读取数据前要向该数据加共享锁,所以共享锁又称为读锁。 2 Oracle 多粒度封锁机制介绍 根据保护对象的不同,Oracle数据库锁可以分为以下几大类: (1) DML lock(data locks,数据锁):用于保护数据的完整性; (2) DDL lock(dictionary locks,字典锁):用于保护数据库对象的结构(例如表、视图、索引的结构定义); (3) internal locks 和l a t c h es(内部锁与闩):保护内部数据库结构; (4) distributed locks(分布式锁):用于OPS(并行服务器)中; (5) PCM locks(并行高速缓存管理锁):用于OPS(并行服务器)中。 本文主要讨论DML(也可称为data locks,数据锁)锁。从封锁粒度(封锁对象的大小)的角度看,Oracle DML锁共有两个层次,即行级锁和表级锁。 2.1 Oracle的TX锁(行级锁、事务锁) 许多对Oracle不太了解的技术人员可能会以为每一个TX锁代表一条被封锁的数据行,其实不然。TX的本义是Transaction(事务),当一个事务第一次执行数据更改(Insert、Update、Delete)或使用SELECT… FOR UPDATE语句进行查询时,它即获得一个TX(事务)锁,直至该事务结束(执行COMMIT或ROLLBACK操作)时,该锁才被释放。所以,一个TX锁,可以对应多个被该事务锁定的数据行。 在Oracle的每行数据上,都有一个标志位来表示该行数据是否被锁定。Oracle不象其它一些DBMS(数据库管理系统)那样,建立一个链表来维护每一行被加锁的数据,这样就大大减小了行级锁的维护开销,也在很大程度上避免了其它数据库系统使用行级封锁时经常发生的锁数量不够的情况。数据行上的锁标志一旦被置位,就表明该行数据被加X锁,Oracle在数据行上没有S锁。

2.2 TM锁(表级锁) 2.2.1 意向锁的引出 表是由行组成的,当我们向某个表加锁时,一方面需要检查该锁的申请是否与原有的表级锁相容;另一方面,还要检查该锁是否与表中的每一行上的锁相容。比如一个事务要在一个表上加S锁,如果表中的一行已被另外的事务加了X锁,那么该锁的申请也应被阻塞。如果表中的数据很多,逐行检查锁标志的开销将很大,系统的性能将会受到影响。为了解决这个问题,可以在表级引入新的锁类型来表示其所属行的加锁情况,这就引出了“意向锁”的概念。 意向锁的含义是如果对一个结点加意向锁,则说明该结点的下层结点正在被加锁;对任一结点加锁时,必须先对它的上层结点加意向锁。如:对表中的任一行加锁时,必须先对它所在的表加意向锁,然后再对该行加锁。这样一来,事务对表加锁时,就不再需要检查表中每行记录的锁标志位了,系统效率得以大大提高。 2.2.2 意向锁的类型 由两种基本的锁类型(S锁、X锁),可以自然地派生出两种意向锁: 意向共享锁(Intent Share Lock,简称IS锁):如果要对一个数据库对象加S锁,首先要对其上级结点加IS锁,表示它的后裔结点拟(意向)加S锁; 意向排它锁(Intent Exclusive Lock,简称IX锁):如果要对一个数据库对象加X锁,首先要对其上级结点加IX锁,表示它的后裔结点拟(意向)加X锁。 另外,基本的锁类型(S、X)与意向锁类型(IS、IX)之间还可以组合出新的锁类型,理论上可以组合出4种,即:S+IS,S+IX,X+IS,X+IX,但稍加分析不难看出,实际上只有S+IX有新的意义,其它三种组合都没有使锁的强度得到提高(即:S+IS=S,X+IS=X,X+IX=X,这里的“=”指锁的强度相同)。所谓锁的强度是指对其它锁的排斥程度。 这样我们又可以引入一种新的锁的类型。 共享意向排它锁(Shared Intent Exclusive Lock,简称SIX锁) :如果对一个数据库对象加SIX锁,表示对它加S锁,再加IX锁,即SIX=S+IX。例如:事务对某个表加SIX锁,则表示该事务要读整个表(所以要对该表加S锁),同时会更新个别行(所以要对该表加IX锁)。 这样数据库对象上所加的锁类型就可能有5种:即S、X、IS、IX、SIX。 具有意向锁的多粒度封锁方法中任意事务T要对一个数据库对象加锁,必须先对它的上层结点加意向锁。申请封锁时应按自上而下的次序进行;释放封锁时则应按自下而上的次序进行;具有意向锁的多粒度封锁方法提高了系统的并发度,减少了加锁和解锁的开销。 2.2.3 Oracle的TM锁(表级锁) Oracle的DML锁(数据锁)正是采用了上面提到的多粒度封锁方法,其行级锁虽然只有一种(即X锁),但其TM锁(表级锁)类型共有5种,分别称为共享锁(S锁)、排它锁(X锁)、行级共享锁(RS锁)、行级排它锁(RX锁)、共享行级排它锁(SRX锁),与上面提到的S、X、IS、IX、SIX相对应。需要注意的是,由于Oracle在行级只提供X锁,所以与RS锁(通过SELECT … FOR UPDATE语句获得)对应的行级锁也是X锁(但是该行数据实际上还没有被修改),这与理论上的IS锁是有区别的。 下表为Oracle数据库TM锁的相容矩阵(Y=Yes,表示相容的请求; N=No,表示不相容的请求;-表示没有加锁请求):

T2

T1 S X RS RX SRX -

----------------------------------------------------

S Y N Y N N Y

X N N N N N Y

RS Y N Y Y Y Y

RX N N Y Y N Y

SRX N N Y N N Y

- Y Y Y Y Y Y

表一:Oracle数据库TM锁的相容矩阵 一方面,当Oracle执行SELECT…FOR UPDATE、INSERT、UPDATE、DELETE等DML语句时,系统自动在所要操作的表上申请表级RS锁(SELECT…FOR UPDATE)或RX锁(INSERT、UPDATE、DELETE),当表级锁获得后,系统再自动申请TX锁,并将实际锁定的数据行的锁标志位置位(指向该TX锁);另一方面,程序或操作人员也可以通过LOCK TABLE语句来指定获得某种类型的TM锁。下表总结了Oracle中各SQL语句产生TM锁的情况: SQL语句 表锁模式 允许的锁模式

-------------------------------------------------------------------------------------------------

Select * from table_name…… 无 RS、RX、S、SRX、X

Insert into table_name…… RX RS、RX

Update table_name…… RX RS、RX

Delete from table_name…… RX RS、RX

Select * from table_name for update RS RS、RX、S、SRX

lock table table_name in row share mode RS RS、RX、S、SRX

lock table table_name in row exclusive mode RX RS、RX

lock table table_name in share mode S RS、S

lock table table_name in share row exclusive mode SRX RS

lock table table_name in exclusive mode X 无

oracle如何实现行级锁

如果当前有用户在对某行数据进行修改登操作,oracle会在这行数据上添加行级锁,期间,所有用户对该行数据只能查询,不可修改,如果比如说执行update操作,需等待该修改操作事务提交或者回滚之后,才行。

oracle数据库怎么锁表

oracle数据库分行级锁和表级锁。用select * from table-name for update完成行级锁。用delete或update完成表级锁。你锁定的资源 别人会等待你的提交语句或回退语句完成以后再继续进行。

如何对“行、表、数据库”加锁?

1\x0d\x0a如何锁一个表的某一行\x0d\x0a\x0d\x0aSETTRANSACTION\x0d\x0aISOLATIONLEVELREADUNCOMMITTED\x0d\x0a\x0d\x0aSELECT*FROMtableROWLOCKWHEREid=1\x0d\x0a\x0d\x0a2锁定数据库的一个表\x0d\x0a\x0d\x0aSELECT*FROMtableWITH(HOLDLOCK)\x0d\x0a\x0d\x0a加锁语句:\x0d\x0asybase:\x0d\x0aupdate表setcol1=col1where1=0\x0d\x0a;\x0d\x0aMSSQL:\x0d\x0aselectcol1from表(tablockx)\x0d\x0awhere\x0d\x0a1=0\x0d\x0a;\x0d\x0aoracle:\x0d\x0aLOCKTABLE表INEXCLUSIVEMODE;\x0d\x0a\x0d\x0a加锁后其它人不可操作,直到加锁用户解锁,用commit或rollback解锁\x0d\x0a\x0d\x0a几个例子帮助大家加深印象\x0d\x0a\x0d\x0a设table1(A,B,C)\x0d\x0aABC\x0d\x0aa1b1c1\x0d\x0aa2b2c2\x0d\x0aa3b3c3\x0d\x0a\x0d\x0a1)排它锁\x0d\x0a新建两个连接\x0d\x0a在第一个连接中执行以下语句\x0d\x0abegintran\x0d\x0aupdatetable1\x0d\x0a\x0d\x0aset\x0d\x0aA='aa'\x0d\x0awhereB='b2'\x0d\x0awaitfordelay\x0d\x0a'00:00:30'--等待30秒\x0d\x0acommittran\x0d\x0a\x0d\x0a在第二个连接中执行以下语句\x0d\x0abegintran\x0d\x0aselect*fromtable1\x0d\x0a\x0d\x0awhereB='b2'\x0d\x0acommittran\x0d\x0a\x0d\x0a若同时执行上述两个语句,则select查询必须等待update执行完毕才能执行即要等待30秒\x0d\x0a\x0d\x0a2)共享锁\x0d\x0a在第一个连接中执行以下语句\x0d\x0abegintran\x0d\x0aselect*fromtable1\x0d\x0aholdlock\x0d\x0a-holdlock人为加锁\x0d\x0awhereB='b2'\x0d\x0awaitfordelay\x0d\x0a'00:00:30'--等待30秒\x0d\x0acommittran\x0d\x0a\x0d\x0a在第二个连接中执行以下语句\x0d\x0abegintran\x0d\x0aselectA,C\x0d\x0afrom\x0d\x0atable1\x0d\x0awhereB='b2'\x0d\x0aupdatetable1\x0d\x0a\x0d\x0aset\x0d\x0aA='aa'\x0d\x0awhereB='b2'\x0d\x0acommittran\x0d\x0a\x0d\x0a若同时执行上述两个语句,则第二个连接中的select查询可以执行\x0d\x0a而update必须等待第一个事务释放共享锁转为排它锁后才能执行\x0d\x0a即要等待30秒\x0d\x0a\x0d\x0a3)死锁\x0d\x0a增设table2(D,E)\x0d\x0aDE\x0d\x0ad1e1\x0d\x0ad2e2\x0d\x0a\x0d\x0a在第一个连接中执行以下语句\x0d\x0abegintran\x0d\x0aupdatetable1\x0d\x0a\x0d\x0aset\x0d\x0aA='aa'\x0d\x0awhereB='b2'\x0d\x0awaitfordelay\x0d\x0a'00:00:30'\x0d\x0aupdatetable2\x0d\x0a\x0d\x0aset\x0d\x0aD='d5'\x0d\x0awhereE='e1'\x0d\x0acommittran\x0d\x0a\x0d\x0a在第二个连接中执行以下语句\x0d\x0abegintran\x0d\x0aupdatetable2\x0d\x0a\x0d\x0aset\x0d\x0aD='d5'\x0d\x0awhereE='e1'\x0d\x0awaitfordelay\x0d\x0a'00:00:10'\x0d\x0aupdatetable1\x0d\x0a\x0d\x0aset\x0d\x0aA='aa'\x0d\x0awhereB='b2'\x0d\x0acommittran\x0d\x0a\x0d\x0a同时执行,系统会检测出死锁,并中止进程\x0d\x0a\x0d\x0a补充一点:\x0d\x0aSqlServer2000支持的表级锁定提示\x0d\x0a\x0d\x0aHOLDLOCK持有共享锁,直到整个事务完成,应该在被锁对象不需要时立即释放,等于SERIALIZABLE事务隔离级别\x0d\x0a\x0d\x0aNOLOCK语句执行时不发出共享锁,允许脏读,等于READ\x0d\x0aUNCOMMITTED事务隔离级别\x0d\x0a\x0d\x0aPAGLOCK在使用一个表锁的地方用多个页锁\x0d\x0a\x0d\x0aREADPAST让sql\x0d\x0aserver跳过任何锁定行,执行事务,适用于READUNCOMMITTED事务隔离级别只跳过RID锁,不跳过页,区域和表锁\x0d\x0a\x0d\x0aROWLOCK\x0d\x0a强制使用行锁\x0d\x0a\x0d\x0aTABLOCKX强制使用独占表级锁,这个锁在事务期间阻止任何其他事务使用这个表\x0d\x0a\x0d\x0aUPLOCK\x0d\x0a强制在读表时使用更新而不用共享锁\x0d\x0a\x0d\x0a应用程序锁:\x0d\x0a应用程序锁就是客户端代码生成的锁,而不是sqlserver本身生成的锁\x0d\x0a\x0d\x0a处理应用程序锁的两个过程\x0d\x0a\x0d\x0asp_getapplock锁定应用程序资源\x0d\x0a\x0d\x0asp_releaseapplock\x0d\x0a为应用程序资源解锁\x0d\x0a\x0d\x0a注意:锁定数据库的一个表的区别\x0d\x0a\x0d\x0aSELECT*FROMtableWITH(HOLDLOCK)\x0d\x0a其他事务可以读取表,但不能更新删除\x0d\x0a\x0d\x0aSELECT*FROMtableWITH(TABLOCKX)\x0d\x0a其他事务不能读取表,更新和删除\x0d\x0a\x0d\x0a1\x0d\x0a如何锁一个表的某一行\x0d\x0a/*\x0d\x0a测试环境:windows2Kserver+Mssql2000\x0d\x0a\x0d\x0a所有功能都进行测试过,并有相应的结果集,如果有什么疑义在论坛跟帖\x0d\x0a\x0d\x0a关于版权的说明:部分资料来自互联网,如有不当请联系版主,版主会在第一时间处理。\x0d\x0a\x0d\x0a功能:sql遍历文件夹下的文本文件名,当然你修改部分代码后可以完成各种文件的列表。\x0d\x0a*/\x0d\x0a\x0d\x0aA\x0d\x0a连接中执行\x0d\x0a\x0d\x0aSETTRANSACTION\x0d\x0aISOLATIONLEVELREPEATABLE\x0d\x0aREAD\x0d\x0a\x0d\x0abegintran\x0d\x0a\x0d\x0aselect*fromtablename\x0d\x0awith\x0d\x0a(rowlock)whereid=3\x0d\x0a\x0d\x0awaitfordelay'00:00:05'\x0d\x0a\x0d\x0acommittran\x0d\x0a\x0d\x0aB连接中如果执行\x0d\x0a\x0d\x0aupdatetablenameset\x0d\x0acolname='10'whereid=3\x0d\x0a--则要等待5秒\x0d\x0a\x0d\x0aupdatetablename\x0d\x0aset\x0d\x0acolname='10'whereid3\x0d\x0a--可立即执行\x0d\x0a\x0d\x0a2\x0d\x0a锁定数据库的一个表\x0d\x0a\x0d\x0aSELECT*FROMtableWITH(HOLDLOCK)\x0d\x0a\x0d\x0a注意:锁定数据库的一个表的区别\x0d\x0a\x0d\x0aSELECT*FROMtableWITH(HOLDLOCK)\x0d\x0a\x0d\x0a其他事务可以读取表,但不能更新删除\x0d\x0a\x0d\x0aSELECT*FROMtableWITH(TABLOCKX)\x0d\x0a\x0d\x0a其他事务不能读取表,更新和删除


文章名称:oracle如何锁定行 oracle行锁会自动释放嘛
URL地址:http://pwwzsj.com/article/hiesse.html