重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
这些是基础,必须掌握:锁定的概念:锁定是数据库用来控制共享资源并发布访问的机制。在多用户环境下,多个用户可同时访问相同的数据。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;这是些扩展的内容,供大家参考
创新互联公司技术团队10年来致力于为客户提供成都网站制作、成都网站设计、外贸营销网站建设、成都品牌网站建设、营销型网站、搜索引擎SEO优化等服务。经过多年发展,公司拥有经验丰富的技术团队,先后服务、推广了上千余家网站,包括各类中小企业、企事单位、高校等机构单位。
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 无
锁表:LOCK TABLE tablename IN 锁模式 MODE;
解锁:commit或rollback;
锁模式有以下几种:
ROW SHARE
ROW SHARE permits concurrent access to the locked table but prohibits users from locking the entire table for exclusive access. ROW SHARE is synonymous with SHARE UPDATE, which is included for compatibility with earlier versions of Oracle Database.
ROW EXCLUSIVE
ROW EXCLUSIVE is the same as ROW SHARE, but it also prohibits locking in SHARE mode. ROW EXCLUSIVE locks are automatically obtained when updating, inserting, or deleting.
SHARE UPDATE
See ROW SHARE.
SHARE
SHARE permits concurrent queries but prohibits updates to the locked table.
SHARE ROW EXCLUSIVE
SHARE ROW EXCLUSIVE is used to look at a whole table and to allow others to look at rows in the table but to prohibit others from locking the table in SHARE mode or from updating rows.
EXCLUSIVE
EXCLUSIVE permits queries on the locked table but prohibits any other activity on it.
lock table 表名 exclusive mode nowait; -- 锁整个表
select * from 表名 where XXX for update nowaitl -- 锁符合条件的记录
一些ORACLE中的进程被杀掉后,状态被置为"killed",但是锁定的资源很长时间不释放,有时实在没办法,只好重启数据库。现在提供一种方法解决这种问题,那就是在ORACLE中杀不掉的,在OS一级再杀。
1.下面的语句用来查询哪些对象被锁:
select object_name,machine,s.sid,s.serial#
from v$locked_object l,dba_objects o ,v$session s
where l.object_id = o.object_id and l.session_id=s.sid;
2.下面的语句用来杀死一个进程:
alter system kill session '24,111'; (其中24,111分别是上面查询出的sid,serial#)
【注】以上两步,可以通过Oracle的管理控制台来执行。
3.如果利用上面的命令杀死一个进程后,进程状态被置为"killed",但是锁定的资源很长时间没有被释放,那么可以在os一级再杀死相应的进程(线程),首先执行下面的语句获得进程(线程)号:
select spid, osuser, s.program
from v$session s,v$process p
where s.paddr=p.addr and s.sid=24 (24是上面的sid)
4.在OS上杀死这个进程(线程):
1)在unix上,用root身份执行命令:
#kill -9 12345(即第3步查询出的spid)
2)在windows(unix也适用)用orakill杀死线程,orakill是oracle提供的一个可执行命令,语法为:
orakill sid thread
其中:
sid:表示要杀死的进程属于的实例名
thread:是要杀掉的线程号,即第3步查询出的spid。
例:c:orakill orcl 12345
oracle数据库分行级锁和表级锁。用select * from table-name for update完成行级锁。用delete或update完成表级锁。你锁定的资源 别人会等待你的提交语句或回退语句完成以后再继续进行。