在线QQ客服:1922638
专业的SQL Server、MySQL数据库同步软件
\ Oracle数据库锁
\
数据库是多个用户使用的共享资源。当多个用户同时访问数据时,数据库中的多个事务将同时访问同一数据。如果您不控制并发操作,则可能会读取和存储不正确的数据,从而破坏数据库的一致性。
锁定是实现数据库并发控制的一项非常重要的技术。当事务对数据对象进行操作时,它首先向系统发送请求以将其锁定。锁定后,事务对数据对象具有一定的控制权。在事务释放锁之前,其他事务无法更新数据对象。
数据库中有两种基本类型的锁:排他锁(Exclusive Locks或X锁)和共享锁(Share Locks或S)锁)。将排他锁添加到数据对象后,其他事务将无法读取和修改它。具有共享锁的数据对象可以被其他事务读取,但是不能被修改。数据库使用这两种基本类型的锁来同时控制数据库事务。
Oracle数据库的锁定类型
根据受保护对象的不同,Oracle数据库锁可以分为以下几类:DML锁(数据锁,数据锁),用于保护数据的完整性; DDL锁(字典锁,字典锁)用于保护数据库对象的结构,例如表,索引等的定义;内部锁和闩锁(内部锁和闩锁)以保护数据库的内部结构。
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锁定,并且可以锁定其他会话。
当TX锁在Oracle数据库中等待时,如果未及时处理,则通常会导致Oracle数据库挂起或导致陷入僵局,从而导致ORA-60错误。这些现象将对实际应用造成极大损害,例如长期无响应,大量事务失败等。
悲观的封锁和乐观的封锁
首先,悲观的封锁
在用户更改锁之前,该锁开始起作用:
选择..进行更新(不等待)
从tab1中选择*以进行更新
用户发出此命令后,Oracle将在返回的数据上建立一个行级块,以防止其他用户进行修改。
如果此时其他用户对上面返回的结果集中的数据执行dml或ddl操作,则将返回错误消息或发生阻塞。
1:对返回结果集的更新或删除操作将被阻止。
2:此表上的ddl操作将报告:Ora-00054:资源正忙并且在没有指定等待的情况下进行获取。
原因分析
此时,Oracle已向返回的结果集中添加了排他的行级锁。对这些数据的所有其他修改或删除操作必须等待此锁的释放。外部现象是其他操作将被阻止。 ,此操作落实或回滚。
同样,此查询的事务将在表中添加表级锁,并且不允许对该表执行任何ddl操作,否则将报告ora-00054错误::资源繁忙,并指定了nowait进行获取。
第二,乐观的封锁
乐观的是,从选择数据到进行积极的更新并提交数据之前,这些数据将不会更改。因为未锁定所选结果集,所以存在潜在的危险,并且有可能被其他用户更改。因此,Oracle仍然建议使用悲观封锁,因为它会更安全。
阻止
定义:
当一个会话在另一会话正在请求的资源上持有锁时,将发生阻塞。被阻止的会话将保持暂停状态,直到持有锁的会话放弃了锁定的资源。 4个常见的dml语句将导致阻塞
插入
更新
删除
选择…进行更新
插入
阻止插入的唯一情况是用户具有带有主键约束的表。当两个会话同时尝试将相同的数据插入表中时,一个会话将被阻塞,直到另一个会话提交或滚动。提交一个会话后,另一会话将收到重复的主键错误。回滚时,被阻止的会话将继续执行。
更新和删除当更新和删除操作的数据行已被另一个会话锁定时,将发生阻塞,直到另一个会话提交或它将滚动。
选择…进行更新
当用户发出select..for更新错误以准备修改返回的结果集时(如果结果集已被另一个用户使用)锁定意味着阻塞。需要等待另一个会话结束才能继续执行。您可以通过发出select…for update nowait语句来避免阻塞。如果该资源已经被另一个会话锁定,则将返回以下错误:Ora-00054:资源正忙并在没有指定等待的情况下进行获取。
死锁-死锁
定义:当两个用户想要保留彼此的资源时,将发生死锁。
也就是说,当两个用户互相等待释放资源时,Oracle确定发生了死锁,在这种情况下,一个用户将被牺牲而另一用户则被牺牲,被牺牲的用户的执行将被回滚。
示例:
1:用户1更新表格A而未提交。
2:用户2更新表B,而不提交表B。
此时,没有资源共享的问题。
3:如果用户2此时更新A表,则会发生阻塞,并且用户1需要等到事务结束。
4:如果用户1此时更新B表,则会发生死锁。此时,Oracle将选择其中一个用户进行翻转,以便另一个用户可以继续执行操作。
原因:
Oracle的死锁问题实际上很少见。如果发生,基本上是由于编程错误引起的。调整后,基本上可以避免死锁。
DML锁分类表
表1 Oracle的TM锁类型
锁定模式
锁定说明
说明
SQL操作
0
没有
\
\
1
NULL
空
选择
2
SS(Row-S)
行级共享锁,其他对象只能查询这些数据行选择更新,锁定更新,锁定行共享
3
SX(行X)
行级互斥锁,提交前不允许DML操作插入,更新,删除,锁定行共享
4
S(共享)
共享锁
创建索引,锁定共享
5
SSX(S/Row-X)
共享的行级互斥锁
锁定共享行独占
6
X(专有)
排他锁
更改表,可拖放,可删除索引,截断表,锁定互斥
\
1.有关V $锁定表和相关视图的注释
\
\
列
数据类型
Description
ADDR
RAW(4 | 8)
锁定状态对象的地址
KADDR
RAW(4 | 8)
锁的地址
SID
数字
用于会话持有或获取锁的标识符
TYPE
VARCHAR2(2)
用户或系统锁定的类型
用户类型上的锁由用户应用程序获得。任何阻止其他进程的进程都可能持有这些锁之一。用户类型锁为:
TM-DML排队\
TX事务入队
UL用户提供
-我们主要关注两种类型的锁,TX和TM
-UL锁由用户自己定义,通常很少定义,基本上不需要关注
-其他是系统锁,将迅速自动释放,无需引起注意
ID1
数字
锁标识符1(取决于类型)
ID2
数字
锁标识符2(取决于类型)
—当锁定类型为TM时,id1是DML锁定对象的object_id
—当锁定类型为TX时,id1为usn + slot,而id2为seq。
-当锁定类型为其他时,请不要关注
LMODE
数字
会话持有锁定的锁定模式:
0-无
1-null(NULL)
2-row-S(SS)
3行-X(SX)
4-share(S)
5-S/Row-X(SSX )
6独占(X)
-大于0时,表示当前会话在某种模式下处于锁定状态,并且等于0。 ,表明当前会话正在等待锁定资源。该会话被阻止。
-通常,发生TX锁定时,它会附带TM锁定,例如,一个sid = 9会话具有TM锁定,并且通常具有一个或多个TX锁,但是它们的id1和id2不同,请注意
Request
数字
锁定模式,进程在其中请求锁定:
0-无
1-null(NULL)
2-row-S(SS)
3行-X(SX)
4-share(S)
5-S/Row-X(SSX )
6独占(X)
-大于0时,表示当前会话被阻止,其他会话具有更改锁的模式
CTIME
NUMBER
自授予当前模式以来的时间
块
数字
锁正在阻止另一把锁
0,” Not Blocking”,
1,”阻止”,
2,”全局”,
-锁是否挡住了另一把锁
\
2.其他相关视图说明
\
视图名称
说明
主字段描述
v $会话
查询会话信息和锁定信息。
sid,序列号:表示会话信息。
program:指示会话的应用程序信息。
row_wait_obj#:指示对象正在等待,与dba_objects中的object_id相对应。
lockwait:等待此会话的锁的地址,对应于v $ lock的kaddr。
v $ session_wait
查询等待的会话信息。
sid:表示持有锁的会话信息。
Seconds_in_wait:指示等待时间信息
事件:表示会话正在等待事件,锁等于入队
\
\
\
dba_locks
v $ lock的格式化视图。
Session_id:对应于v $锁中的Sid。
Lock_type:对应于v $ lock中的类型。
Lock_ID1:对应于v $ lock中的ID1。
Mode_held,mode_requested:和v $ lock
对应于lmode,请求。
v $已锁定对象
仅包含DML锁定信息,包括回滚段和会话信息。
Xidusn,xidslot,xidsqn:指示回滚段信息。和
v $交易已关联。
Object_id:指示锁定的对象ID。
Session_id:表示持有锁的会话信息。
Locked_mode:表示会话正在等待的锁定模式的字母
兴趣,它与v $ lock中的lmode相同。
\
1.查询数据库中的锁
选择* from v $ lock;
从v $ lock中选择*,其中block = 1;
2.查询锁定的对象
从v $ lock_object中选择*;
3.查询阻止
检查被阻止的会话
从v $ lock中选择*,其中lmode = 0且\\ n输入(” TM”,” TX”);
检查阻止其他会话锁
从v $ lock中选择*,其中lmode> 0和\\ n00;输入(” TM”,” TX”);
4.查询数据库的过程正在等待锁
从v $会话中选择*,其中lockwait不为null;
5.查询会话之间的锁等待关系
\
选择 a.sid holdid,b.sid waitsid, 类型,a.id1,a.id2,a.ctime \ 来自 \ v $锁a,v $锁b
其中 a.id1 = b.id1 和 \ a.id2 = b.id2 和 \一个。 块 = 1 \\ n 和 \ b。 块 = 0;
6.查询锁等待事件
选择* from v $ session_wait其中event =” enqueue”;
\
解决方案:
\ 选择\来自v $ locked_object的session_id; \-首先获取锁定对象的session_id
\ SELECT sid,序列号,用户名,osuser FROM v $会话,其中sid = \ session_id; 使用上面获得的session_id获取v $会话的sid和序列号,然后终止该过程。
ALTER SYSTEM KILL SESSION” sid,serial”;
例如:
ALTER SYSTEM KILL SESSION” 13,8″;