Oracle锁基础知识

001 引言
    在任何多用户数据库应用程序中,最终免不了会出现两个用户希望同时使用同一行的情况。数据库必须确保这在物理上不可能实现。事务的隔离性原则要求数据库确保:在一个会话的事务完成之前,另一个会话的事务不能影响此会话。为此,数据库必须对数据的并发访问进行串行化,必须确保即使多个会话请求同一行,它们实际上要按顺序排队。
    借助于记录和表锁定机制,我们可以实现并发访问的串行化。Oracle数据库中的锁定是完全自动的。一般而言,只有在软件用质量较差的代码干扰自动锁定机制时,或业务分析出错导致会使会话发生冲突的业务模型时,才会引发某些问题。

002 共享锁与排它锁
    Oracle数据库中锁定的标准级别保证了最大可能的并发级别。也就是说,如果某个会话正在更新一行,那么只有这行会被锁定。此外锁定这一行只是为了防止其它会话对其进行更新,其它会话可以随时执行读取操作。只有在使用commit或rollback命令结束事务之后,锁定才会被解除。这种锁定是一个“排它(exclusive)”锁:在指定记录上请求排它锁的第一个会话会得到这个锁定,其它请求对该记录进行写访问的会话则必须等待。虽然这一行已通过锁定会话进行了更新,但是对其进行读访问是被允许的(而且经常会出现这种情况),并且这些读操作会涉及撤销数据的使用,从而确保读会话并不会看到任何未被提交的变更。
    对于一行或一个完整表上的排它锁来说,每次只能有一个会话可以获得这个排它锁,不过许多会话可以同时获得同一对象上的“共享(shared)”锁。在一行上设置共享锁毫无意义,其原因在于锁定一行的唯一目的就是不允许其它会话更改它。共享锁被置于整个表上,同时许多会话可以获得同一个表上的共享锁。在一个表上放置共享锁的目的是为了防止另一个会话获得这个表上的排它锁(在已存在共享锁的情况下无法再获得排它锁)。在表上放置排它锁时需要执行DDL语句。如果其它会话已经在一个表上放置共享锁,那么我们就无法执行修改某个对象的语句(例如删除这个表的一列)。
    为了在行上执行DML语句,当前会话必须获得待更改行上的排它锁以及包含这些行的表上的共享锁。如果另一个会话已经获取了待更改行上的排它锁,那么当前会话将被挂起,直至使用commit或rollback命令解除这些锁定。如果另一个会话已经获取了表上的共享锁以及其它行上的排它锁,那么就不存在任何问题。一个表上的排它锁也是允许的,但是,除非DDL语句要求这么做,默认锁定机制是不锁定整个表。
    所有DML语句至少都需要两种锁:受影响记录上的排它锁,以及包含受影响记录的表上的共享锁。排它锁能够防止其它会话干预指定的行,而共享锁则能够组织其它会话使用DDL语句修改表的定义。这两种锁定会被自动请求。如果某条DML语句在指定记录上无法获取所需的排它锁,那么会挂起这条语句直至获得所需的排它锁。
    执行DDL命令需要使用所涉及对象上的排它锁。只有在针对指定表的所有DML事务结束,且行上的排它锁以及表上的共享锁都被解除之后,我们才可以获得执行DDL命令所需的排它锁。任何DDL语句所需的排它锁都是被自动请求的。但是,如果无法获取所需的排它锁(通常是因为其它会话已经获得用于 DML语句的共享锁),那么DDL语句会由于错误立即终止。

003 排队机制
    请求锁定需要排队。如果某个会话请求一个锁定,但由于其它会话已经锁定了指定行或对象而无法获得所需的锁定,那么这个会话将会等待。此时,可能有多个会话都在等待访问相同的记录或对象,在这种情况下,Oracle会跟踪这些会话请求锁定的顺序。当使用锁定的会话解除锁定时,下一个会话将获得授权,以此类推。这种机制被称为“排队(enqueue)”机制。
    如果不希望某个会话在无法获取锁定时进行排队,那么避免排队的唯一方式是使用select...for update命令的wait或nowait子句。因为select语句并不需要任何锁定,所以普通的select语句能够成功地执行,但是,DML语句则会被挂起。

未完待续

时间: 2024-09-20 04:23:48

Oracle锁基础知识的相关文章

ORACLE字符集基础知识

概念描叙 ORACLE数据库有国家字符集(national character set)与数据库字符集(database character set)之分.两者都是在创建数据库时需要设置的.国家字符集主要是用于NCHAR.NVARCHAR.NCLOB类型的字段数据,而数据库字符集使用很广泛,它用于:CHAR.VARCHAR.CLOB.LONG类型的字段数据: ORACLE的字符集名字一般由以下部分组成:语言或区域.表示一个字符的比特位数.标准字符集名称(可选项,S或C,表示服务器或客户端).OR

你必须了解的Oracle存储过程基础知识

商业规则和业务逻辑可以通过程序存储在Oracle中,这个程序就是存储过程. 存储过程是SQL, PL/SQL, Java 语句的组合,它使你能将执行商业规则的代码从你的应用程序中移动到数据库.这样的结果就是,代码存储一次但是能够被多个程序使用. 要创建一个过程对象(procedural object),必须有 CREATE PROCEDURE 系统权限.如果这个过程对象需要被其他的用户schema 使用,那么你必须有 CREATE ANY PROCEDURE 权限.执行 procedure 的时

sql注入之必备的基础知识_数据库其它

什么是SQL注入(SQL Injection) 所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令.在某些表单中,用户输入的内容直接用来构造(或者影响)动态SQL命令,或作为存储过程的输入参数,这类表单特别容易受到SQL注入式攻击. mysql常用注释     #     --[空格]或者是--+     /*-*/ 在注意过程中,这些注释可能都需要进行urlencode. mysql认证绕过       ;%00     

Oracle基础知识-数据迁移

我们常需要对Oracle数据库进行迁移,迁移到更加高级的主机上.迁移到远程的机房上.迁移到不同的平台下 一.exp/imp: 这也算是最常用最简单的方法了,一般是基于应用的owner级做导出导入. 操作方法为:在新库建立好owner和表空间,停老库的应用,在老库做 [sql] view plaincopyprint? exp user/pwd owner=XXX file=exp_xxx.dmp log=exp_xxx.log buffer=6000000 传dmp文件到新库,在新库做 [sql

Oracle基础知识-启动Oracle常见疑难问题分析

实例和数据库的启动与关闭是DBA的重要职责之一.只有打开数据库,其他用户才能对数据库中的数据进行操作.一旦数据库关闭,便不能对其操作.对于DBA们来说,关闭和重新启动数据库以便优化.调整应用程序的运行是经常碰到的事情.如果用户已经进入了数据库,使用SHUTDOWN IMMEDIATE 或SHUTDOWN ABORT命令来执行关闭数据库,则用户将失去连接,直到数据库重新启动.经常关闭和启动会对数据库性能造成一定的影响,当然也会影响到用户对数据库的使用.本文从管理数据库的角度来分析在Oracle启动

Oracle基础知识-Oracle不同的启动关闭方式

Oracle中不同启动和关闭方式的区别 Oracle数据库提供了几种不同的数据库启动和关闭方式,本文将周详介绍这些启动和关闭方式之间的区别连同他们各自不同的功能.一.启动和关闭Oracle数据库 对于大多数Oracle DBA来说,启动和关闭Oracle数据库最常用的方式就是在命令行方式下的Server Manager.从Oracle 8i以后,系统将Server Manager的任何功能都集中到了SQL*Plus中,也就是说从8i以后对于数据库的启动和关闭能够直接通过SQL*Plus来完成,而

Oracle基础知识-oracle常用命令

日志管理 1.forcing log switches [sql] view plaincopyprint? sql> alter system switch logfile; 2.forcing checkpoints [sql] view plaincopyprint? sql> alter system checkpoint; 3.adding online redo log groups [sql] view plaincopyprint? sql> alter database

Oracle基础知识-SQL简单命令

SQL语句包括两个部分:1 DDL 数据定义语言 2 DML 数据控制语言 DDL: create:创建一个表 [html] view plaincopyprint? create table b( clob char(1) ); alter:增加已经定义的表列的分配 drop:删除一个表 desc:查看一个表的定义 DML: selelct: [html] view plaincopyprint? select * from b; insert: [html] view plaincopypr

Oracle基础知识-sqlplus使用

Oracle的sql*plus是与oracle进行交互的客户端工具. 在sql*plus中,可以运行sql*plus命令与sql*plus语句. 我们通常所说的DML(数据操纵语言).DDL(数据定义语言).DCL(数据库控制语言)都是sql*plus语句,它们执行完后,都可以保存在一个被称为sql buffer的内存区域中,并且只能保存一条最近执行的sql语句,我们可以对保存在sql buffer中的sql 语句进行修改,然后再次执行,sql*plus一般都与数据库打交道.除了sql*plus