锁这玩意其实就是资源不够用的,需要排队来获取资源,就像过去大杂院里只有一个公共厕所,一大早很多少排队一样,等。操作系统有锁,数据库也有锁,这里锁的道理是一样的。
数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。
加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。
在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两种基本的锁类型来对数据库的事务进行并发控制。
根据保护的对象不同,Oracle数据库锁可以分为以下几大类:DML锁(data locks,数据锁),用于保护数据的完整性;DDL锁(dictionary locks,字典锁),用于保护数据库对象的结构,如表、索引等的结构定义;内部锁和闩(internal locks and latches),保护数据库的内部结构。
接下来主要讲dml锁
DML锁分类表
表1 Oracle的TM锁类型 | |||
锁模式 | 锁描述 | 解释 | SQL操作 |
0 | none | ||
1 | NULL | 空 | Select |
2 | SS(Row-S) | 行级共享锁,其他对象只能查询这些数据行 | Select for update、Lock for update、Lock row share |
3 | SX(Row-X) | 行级排它锁,在提交前不允许做DML操作 | Insert、Update、Delete、Lock row share |
4 | S(Share) | 共享锁 | Create index、Lock share |
5 | SSX(S/Row-X) | 共享行级排它锁 | Lock share row exclusive |
6 | X(Exclusive) | 排它锁 | Alter table、Drop able、Drop index、Truncate table 、Lock exclusive |
这里用户拥有模式高的锁可以操作其它拥有模式低锁的对象。
1.关于 V$lock表和相关视图的说明
这里补充一下:
可用block查死锁,用lmode查对象和用户是否持有锁或者是否被锁。
其它相关视图说明
视图名 | 描述 | 主要字段说明 |
v$session | 查询会话的信息和锁的信息。 | sid,serial#:表示会话信息。 program:表示会话的应用程序信息。 row_wait_obj#:表示等待的对象,和dba_objects中的object_id相对应。 lockwait :该会话等待的锁的地址,与v$lock的kaddr对应. |
v$session_wait | 查询等待的会话信息。 | sid:表示持有锁的会话信息。 Seconds_in_wait:表示等待持续的时间信息 Event:表示会话等待的事件,锁等于enqueue |
dba_locks | 对v$lock的格式化视图。 | Session_id:和v$lock中的Sid对应。 Lock_type:和v$lock中的type对应。 Lock_ID1: 和v$lock中的ID1对应。 Mode_held,mode_requested:和v$lock中 的lmode,request相对应。 |
v$locked_object | 只包含DML的锁信息,包括回滚段和会话信息。 | Xidusn,xidslot,xidsqn:表示回滚段信息。和 v$transaction相关联。 Object_id:表示被锁对象标识。 Session_id:表示持有锁的会话信息。 Locked_mode:表示会话等待的锁模式的信 息,和v$lock中的lmode一致。 |
这里是关于锁的视图,关于锁基本信息都可查到。
死锁:
定义:当两个用户希望持有对方的资源时就会发生死锁.
即两个用户互相等待对方释放资源时,oracle认定为产生了死锁,在这种情况下,将以牺牲一个用户作为代价,另一个用户继续执行,牺牲的用户的事务将回滚.
例子:
1:用户1对A表进行Update,没有提交。
2:用户2对B表进行Update,没有提交。
此时双反不存在资源共享的问题。
3:如果用户2此时对A表作update,则会发生阻塞,需要等到用户一的事物结束。
4:如果此时用户1又对B表作update,则产生死锁。此时Oracle会选择其中一个用户进行会滚,使另一个用户继续执行操作。
起因:
Oracle的死锁问题实际上很少见,如果发生,基本上都是不正确的程序设计造成的,经过调整后,基本上都会避免死锁的发生。
最后谈谈锁来自何方:
在Oracle 数据库中,它并不是对某个表加上锁或者某几行加上锁,锁是以数据块的一个属性存在的。也就是说,每个数据块本身就存储着自己数据块中数据的信息,这个地方叫ITL(Interested Transaction List),凡是在这个数据块上Tianlesoftware
有活动的事务,它的信息就会记录在这里面供后续的操作查询,一保证事务的一致性。