介绍一下Oracle悲观锁和乐观锁

合集下载

数据库简答题

数据库简答题

数据库简答题数据库是一种用于存储和管理数据的系统。

它可以提供有效的数据组织和快速的数据访问。

下面是一些与数据库相关的简答题:1. 什么是数据库管理系统(DBMS)?数据库管理系统是一种软件,用于管理数据库的创建、使用和维护。

它提供了一种访问数据库的接口,并允许用户进行数据的插入、修改、删除和查询操作。

常见的DBMS包括MySQL、Oracle、SQL Server等。

2. 请解释什么是关系型数据库?关系型数据库是以表格形式组织数据的数据库。

它利用关系模型来描述数据之间的关系,表格中的每一行表示一个实体,每一列表示一个属性。

关系型数据库使用结构化查询语言(SQL)进行数据的管理和操作。

3. 什么是主键?它的作用是什么?主键是一种唯一标识表格中每一行数据的列。

它的作用是保证数据的唯一性和完整性,能够快速找到和区分每一条记录。

主键可以由一个或多个列组成,在表格中不能重复。

4. 请解释什么是外键?它的作用是什么?外键是一种用于建立表格之间关联关系的列。

它是另一张表格的主键,用来引用其他表格中的数据。

外键的作用是维护数据的完整性,确保相关表格之间的关系一致。

5. 什么是索引?它的作用是什么?索引是一种用于提高数据库查询效率的数据结构。

它类似于书的目录,可以快速定位和访问数据。

数据库查询时会先根据索引找到相关的数据位置,然后再进行数据的读取。

索引可以加快数据的查询速度,但同时也会增加数据的存储和维护成本。

6. 数据库的三范式是什么?为什么要遵循三范式?数据库的三范式是一种设计数据库的规范。

它包括第一范式(1NF)、第二范式(2NF)和第三范式(3NF)。

遵循三范式可以提高数据库的设计和管理效率,降低数据冗余和数据不一致的风险。

- 第一范式(1NF)要求数据表格中的每一列都是不可再分的基本数据单元,每一行数据应为唯一。

- 第二范式(2NF)要求每个非主键列完全依赖于主键。

- 第三范式(3NF)要求非主键列之间不能存在传递依赖。

oracle锁表问题处理

oracle锁表问题处理

oracle锁表问题处理查询表的状况的对象:V$LOCK, V$LOCKED_OBJECT, V$SESSION, V$SQLAREA, V$PROCESS select * from v$locked_objectselect * from dba_objects方法:首先查看哪些表被锁住了select b.owner,b.object_name,a.session_id,a.locked_modefrom v$locked_object a,dba_objects bwhere b.object_id = a.object_id;select ername,b.sid,b.serial#,logon_timefrom v$locked_object a,v$session bwhere a.session_id = b.sid order by b.logon_time;杀进程中的会话alter system kill session 'sid,serial#';例如:alter system kill session '29,5497';查询锁表的方法:SELECT S.SID SESSION_ID, ERNAME, s.SERIAL#,DECODE(LMODE, 0, 'None', 1, 'Null', 2, 'Row-S (SS)', 3, 'Row-X (SX)', 4, 'Share', 5, 'S/Row-X (SSX)', 6, 'Exclusive',TO_CHAR(LMODE)) MODE_HELD, DECODE(REQUEST, 0, 'None', 1, 'Null', 2, 'Row-S (SS)', 3, 'Row-X (SX)', 4, 'Share', 5, 'S/Row-X (SSX)', 6, 'Exclusive',TO_CHAR(REQUEST)) MODE_REQUESTED, O.OWNER||'.'||O.OBJECT_NAME||' ('||O.OBJECT_TYPE||')',S.TYPE LOCK_TYPE, L.ID1 LOCK_ID1, L.ID2 LOCK_ID2FROM V$LOCK L, SYS.DBA_OBJECTS O, V$SESSION SWHERE L.SID = S.SID AND L.ID1 = O.OBJECT_ID ;解锁方法:ALTER SYSTEM KILL SESSION 'SID,SERIR#'0----------0--------SQL> alter system kill session '1679,2456';alter system kill session '1679,2456'*ERROR at line 1:ORA-01031: insufficient privilegesgrant execute on p_kill_user_session to rtgs_liush();操作的时候用命令:EXEC SYS.P_KILL_USER_SESSION(1679);------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------数据库锁表的分析与解决上面介绍了内存溢出的原因和处理方法,下面再介绍一下数据库锁表及阻塞的原因和处理办法。

oracle 存储过程并发写法

oracle 存储过程并发写法

oracle 存储过程并发写法在Oracle数据库中,并发是指多个用户或进程同时访问数据库的能力。

在并发环境下,存储过程的设计和实现需要考虑到并发性,以确保数据的一致性和安全性。

下面是一些常见的Oracle存储过程并发写法。

1.悲观并发控制(Pessimistic Concurrency Control)悲观并发控制是指在操作数据之前,事先假设其他用户或进程会对相同的数据进行修改,因此需要采取锁机制来保护数据。

在Oracle 中,可以使用行级锁来实现悲观并发控制。

在存储过程中,可以使用以下方法实现悲观并发控制:-使用SELECT ... FOR UPDATE语句,在读取数据时对数据进行加锁,防止其他用户并发修改。

-使用LOCK TABLE语句,对需要修改的表进行锁定,防止其他用户并发访问。

-使用排他锁(exclusive lock),只允许一个用户修改数据,其他用户需要等待锁释放。

悲观并发控制的缺点是会对性能产生一定的影响,因为需要等待锁的释放。

此外,如果锁的粒度过大,也会导致并发性下降。

2.乐观并发控制(Optimistic Concurrency Control)乐观并发控制是指在操作数据之前,并不主动加锁,而是在提交事务时检查数据是否被其他用户修改过。

在Oracle中,可以通过使用版本号或时间戳来实现乐观并发控制。

在存储过程中,可以使用以下方法实现乐观并发控制:-在表中添加一个版本号或时间戳字段,并在读取和更新数据时进行比较和更新。

-使用MERGE语句,在更新数据时同时检查数据是否被其他事务修改过。

乐观并发控制的优点是不需要加锁,对性能影响较小。

但是如果多个用户并发修改同一行数据,则可能发生冲突,需要进行冲突处理。

3.分段锁(Partition Locking)分段锁是指将数据分成多个段,并对每个段进行锁定,以实现高并发。

在Oracle中,可以通过使用分区(Partitioning)来实现分段锁。

oracle必问的面试题

oracle必问的面试题

oracle必问的面试题在面试过程中,许多公司都倾向于针对Oracle数据库进行提问。

作为一种常见的数据库管理系统,Oracle在企业级应用中扮演着重要的角色。

因此,掌握Oracle的相关知识对于求职者来说非常必要。

本文将介绍一些必问的Oracle面试题,帮助读者准备面试。

1. 什么是Oracle数据库?Oracle是一种关系型数据库管理系统(RDBMS),由Oracle公司开发。

它通过使用结构化查询语言(SQL)进行数据管理和查询。

Oracle数据库广泛应用于企业级应用,包括金融、制造、电信等领域。

2. 介绍一下Oracle数据库的体系结构。

Oracle数据库的体系结构由多个组件组成,包括实例、数据库和存储。

实例是内存结构和后台进程的组合,用于管理数据库。

数据库是存储数据的物理文件集合。

存储是用于存储和检索数据的物理设备,如硬盘。

3. 什么是表空间和数据文件?表空间是Oracle数据库中逻辑存储单位,用于存储表、索引和其他对象。

每个表空间由一个或多个数据文件组成。

数据文件是物理文件,用于在磁盘上存储数据。

4. 如何创建用户和授权?使用CREATE USER语句可以创建用户,语法如下:CREATE USER username IDENTIFIED BY password;要授予用户权限,可以使用GRANT语句,语法如下:GRANT privilege1, privilege2, ... ON object_name TO username;5. 介绍一下Oracle的锁机制。

Oracle使用各种锁来实现并发控制。

共享锁(Shared Lock)用于读取数据,排他锁(Exclusive Lock)用于修改数据。

Oracle还支持行级锁和表级锁,以及乐观锁和悲观锁等不同类型的锁机制。

6. 如何备份和恢复Oracle数据库?可以使用Oracle提供的工具来备份和恢复数据库,例如使用RMAN(Recovery Manager)进行备份和恢复操作。

oracle锁原理

oracle锁原理

Oracle锁原理详解1. 概述在Oracle数据库中,锁是用于控制并发访问的一种机制。

当多个用户同时访问数据库时,为了保证数据的一致性和完整性,Oracle会对数据进行加锁,以防止其他用户对数据的修改。

本文将详细介绍Oracle锁的基本原理。

2. 锁的类型Oracle中的锁可以分为两种类型:共享锁(Shared Lock)和排他锁(Exclusive Lock)。

•共享锁:多个事务可以同时获取共享锁,并且可以并发读取数据,但不能修改数据。

共享锁用于保证数据的一致性,即多个事务可以同时读取相同的数据,但不能同时修改数据。

•排他锁:只有一个事务可以获取排他锁,并且其他事务不能同时获取共享锁或排他锁。

排他锁用于保证数据的完整性,即一个事务在修改数据时,其他事务不能同时读取或修改数据。

3. 锁的级别Oracle中的锁可以分为多个级别,包括表级锁、行级锁和字段级锁。

•表级锁:锁定整个表,阻止其他事务对表的修改。

表级锁对于大型表来说,可能会导致性能问题,因为它会阻塞其他事务的访问。

•行级锁:锁定表中的一行数据,其他事务可以并发读取其他行的数据。

行级锁可以更细粒度地控制并发访问,但可能会导致死锁问题。

•字段级锁:锁定表中的一个或多个字段,其他事务可以并发读取或修改其他字段的数据。

字段级锁可以进一步细化锁的粒度,但也可能导致死锁问题。

4. 锁的控制Oracle中的锁由数据库管理系统(DBMS)自动控制,用户无需手动操作。

当一个事务对数据进行修改时,DBMS会自动为该数据加上相应的锁,并在事务提交或回滚后释放锁。

锁的控制是通过锁定机制和并发控制机制实现的。

•锁定机制:当一个事务对数据进行修改时,DBMS会自动为该数据加上相应的锁。

锁定机制可以保证在并发访问时,每个事务都能正确地读取和修改数据。

•并发控制机制:当多个事务同时访问数据库时,DBMS会根据事务的隔离级别来控制并发访问。

并发控制机制可以避免脏读、不可重复读和幻读等问题。

并发控制的方法

并发控制的方法

并发控制的方法
并发控制是指在多个用户或进程同时访问共享资源时,保证数据一致性和完整性的一种技术。

下面介绍几种常见的并发控制方法。

1. 乐观并发控制
乐观并发控制是指在多个用户或进程同时访问共享资源时,先不加锁,而是在提交操作时检查是否有冲突。

如果有冲突,则回滚事务,重新尝试。

这种方法适用于并发冲突较少的场景,能够提高并发性能。

2. 悲观并发控制
悲观并发控制是指在多个用户或进程同时访问共享资源时,先加锁,保证每个用户或进程的操作互不干扰。

这种方法适用于并发冲突较多的场景,能够保证数据的一致性和完整性。

3. 两阶段锁
两阶段锁是指在执行事务时,先获取所有需要的锁,然后执行操作,最后释放所有锁。

这种方法能够保证数据的一致性和完整性,但是会降低并发性能。

4. 时间戳并发控制
时间戳并发控制是指在每个事务开始时,给事务赋予一个时间戳,每个数据项也有一个时间戳。

在执行操作时,比较事务时间戳和数据项时间戳,如果事务时间戳早于数据项时间戳,则执行操作,否则回滚事务。

这种方法能够保证数据的一致性和完整性,但是会增加系统开销。

5. 多版本并发控制
多版本并发控制是指在每个数据项中存储多个版本,每个版本有一个时间戳。

在执行操作时,选择最新的版本进行操作。

这种方法能够提高并发性能,但是会增加系统开销。

以上是几种常见的并发控制方法,不同的方法适用于不同的场景,需要根据具体情况选择合适的方法。

乐观锁和悲观锁的区别

乐观锁和悲观锁的区别

乐观锁和悲观锁的区别乐观锁在关系数据库管理系统⾥,乐观并发控制(⼜名”乐观锁”,Optimistic Concurrency Control,缩写”OCC”)是⼀种并发控制的⽅法。

它假设多⽤户并发的事务在处理时不会彼此互相影响,各事务能够在不产⽣锁的情况下处理各⾃影响的那部分数据。

在提交数据更新之前,每个事务会先检查在该事务读取数据后,有没有其他事务⼜修改了该数据。

如果其他事务有更新的话,正在提交的事务会进⾏回滚。

乐观事务控制最早是由孔祥重(H.T.Kung)教授提出。

乐观并发控制的阶段乐观并发控制的事务包括以下阶段:1. 读取:事务将数据读⼊缓存,这时系统会给事务分派⼀个时间戳。

2. 校验:事务执⾏完毕后,进⾏提交。

这时同步校验所有事务,如果事务所读取的数据在读取之后⼜被其他事务修改,则产⽣冲突,事务被中断回滚。

3. 写⼊:通过校验阶段后,将更新的数据写⼊数据库。

乐观并发控制多数⽤于数据争⽤不⼤、冲突较少的环境中,这种环境中,偶尔回滚事务的成本会低于读取数据时锁定数据的成本,因此可以获得⽐其他并发控制⽅法更⾼的吞吐量。

相对于悲观锁,在对数据库进⾏处理的时候,乐观锁并不会使⽤数据库提供的锁机制。

⼀般的实现乐观锁的⽅式就是记录数据版本。

数据版本,为数据增加的⼀个版本标识。

当读取数据时,将版本标识的值⼀同读出,数据每更新⼀次,同时对版本标识进⾏更新。

当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第⼀次取出来的版本标识进⾏⽐对,如果数据库表当前版本号与第⼀次取出来的版本标识值相等,则予以更新,否则认为是过期数据。

实现数据版本有两种⽅式,第⼀种是使⽤版本号,第⼆种是使⽤时间戳。

使⽤版本号实现乐观锁使⽤版本号时,可以在数据初始化时指定⼀个版本号,每次对数据的更新操作都对版本号执⾏+1操作。

并判断当前版本号是不是该数据的最新的版本号。

使⽤版本号实现乐观锁使⽤版本号时,可以在数据初始化时指定⼀个版本号,每次对数据的更新操作都对版本号执⾏+1操作。

oracle 锁详解

oracle 锁详解

oracle 锁详解在 Oracle 数据库中,锁(Lock)用于控制并发访问和确保数据的一致性。

锁是一种机制,它可以限制对特定资源(如表、行、记录等)的访问,以防止并发事务之间的冲突和数据不一致。

Oracle 中的锁可以分为以下几种类型:1. **共享锁(Shared Lock)**:也称为读锁,用于读取数据并确保多个事务可以同时读取相同的数据,而不会相互阻塞。

共享锁可以与其他共享锁共存,但与排他锁互斥。

2. **排他锁(Exclusive Lock)**:也称为写锁,用于对数据进行写入操作,并确保在同一时间只有一个事务可以获取排他锁。

排他锁会阻止其他事务获取共享锁或排他锁。

3. **行级锁 (Row-Level Lock)**:用于锁定表中的特定行,以提供更细粒度的并发控制。

行级锁可以是共享锁或排他锁。

4. **表级锁(Table-Level Lock)**:用于锁定整个表,阻止其他事务对表进行读写操作。

表级锁通常会影响并发性能,因此在 Oracle 中较少使用。

Oracle 数据库自动管理和协调锁的获取和释放。

在执行 DML (数据操作语言)语句时,Oracle 会根据需要自动获取适当类型的锁。

例如,在执行 SELECT 语句时,Oracle 会获取共享锁;而在执行 INSERT、UPDATE 或 DELETE 语句时,Oracle 会获取排他锁。

锁的粒度和类型可以根据事务的隔离级别进行设置。

Oracle 提供了多种隔离级别,如 READ COMMITTED、SERIALIZABLE 等,每个隔离级别都对应不同的锁行为。

了解和管理锁对于确保数据库的并发性能和数据一致性非常重要。

Oracle 数据库提供了一些视图和工具来监控和诊断锁的信息,例如 V$LOCK、V$SESSION 等视图。

如果在应用程序中遇到锁冲突或性能问题,可以使用这些工具来分析和解决锁相关的问题。

请注意,以上是 Oracle 锁的一些基本概念和类型,Oracle 数据库的锁机制非常复杂,并且还有其他更高级的锁类型和特性。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

介绍一下Oracle悲观锁和乐观锁
为了得到最大的性能,一般数据库都有并发机制,不过带来的问题就是数据访问的冲突。

为了解决这个问题,大多数数据库用的方法就是数据的锁定。

数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁。

什么叫悲观锁呢,悲观锁顾名思义,就是对数据的冲突采取一种悲观的态度,也就是说假设数据肯定会冲突,所以在数据开始读取的时候就把数据锁定住。

而乐观锁就是认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让用户返回错误的信息,让用户决定如何去做。

先从悲观锁开始说。

在SqlServer等其余很多数据库中,数据的锁定通常采用页级锁的方式,也就是说对一张表内的数据是一种串行化的更新插入机制,在任何时间同一张表只会插1条数据,别的想插入的数据要等到这一条数据插完以后才能依次插入。

带来的后果就是性能的降低,在多用户并发访问的时候,当对一张表进行频繁操作时,会发现响应效率很低,数据库经常处于一种假死状态。

而Oracle用的是行级锁,只是对想锁定的数据才进行锁定,其余的数据不相干,所以在对Oracle表中并发插数据的时候,基本上不会有任何影响。

注:对于悲观锁是针对并发的可能性比较大,而一般在我们的应用中用乐观锁足以。

Oracle的悲观锁需要利用一条现有的连接,分成两种方式,从SQL语句的区别来看,就
是一种是for update,一种是for update nowait的形式。

比如我们看一个例子。

首先建立测试用的数据库表。

CREATE TABLE TEST(ID,NAME,LOCATION,VALUE,CONSTRAINT test_pk PRIMARY KEY(ID))AS SELECT deptno, dname, loc, 1 FROM scott.dept这里我们利用了Oracle的Sample的scott用户的表,把数据copy到我们的test表中。

首先我们看一下for update锁定方式。

首先我们执行如下的select for update语句。

select * from test where id = 10 for update通过这条检索语句锁定以后,再开另外一个sql*plus窗口进行操作,再把上面这条sql语句执行一便,你会发现sqlplus好像死在那里了,好像检索不到数据的样子,但是也不返回任何结果,就属于卡在那里的感觉。

这个时候是什么原因呢,就是一开始的第一个Session中的select for update语句把数据锁定住了。

由于这里锁定的机制是wait的状态(只要不表示nowait 那就是wait),所以第二个Session(也就是卡住的那个sql*plus)中当前这个检索就处于等待状态。

当第一个session最后commit或者rollback之后,第二个session中的检索结果就是自动跳出来,并且也把数据锁定住。

不过如果你第二个session中你的检索语句如下所示。

select * from test where id = 10也就是没有for update这种锁定数据的语句的话,就不会造成阻塞了。

另外一种情况,就是当数据库数据被锁定的时候,也就是执行刚才for update那条sql以后,我们在另外一个session中执行for update nowait后又是什么样呢。

比如如下的sql语句。

由于这条语句中是制定采用nowait
方式来进行检索,所以当发现数据被别的session锁定中的时候,就会迅速返回ORA-00054错误,内容是资源正忙, 但指定以NOWAIT 方式获取资源。

所以在程序中我们可以采用nowait方式迅速判断当前数据是否被锁定中,如果锁定中的话,就要采取相应的业务措施进行处理。

select * from test where id = 10 for update nowait那这里另外一个问题,就是当我们锁定住数据的时候,我们对数据进行更新和删除的话会是什么样呢。

比如同样,我们让第一个Session锁定住id=10的那条数据,我们在第二个session中执行如下语句。

update test set value=2 where id = 10这个时候我们发现update语句就好像select for update语句一样也停住卡在这里,当你第一个session放开锁定以后update才能正常运行。

当你update运行后,数据又被你update 语句锁定住了,这个时候只要你update后还没有commit,别的session照样不能对数据进行锁定更新等等。

总之,Oracle中的悲观锁就是利用Oracle的Connection对数据进行锁定。

在Oracle中,用这种行级锁带来的性能损失是很小的,只是要注意程序逻辑,不要给你一不小心搞成死锁了就好。

而且由于数据的及时锁定,在数据提交时候就不呼出现冲突,可以省去很多恼人的数据冲突处理。

缺点就是你必须要始终有一条数据库连接,就是说在整个锁定到最后放开锁的过程中,你的数据库联接要始终保持住。

与悲观锁相对的,我们有了乐观锁。

乐观锁一开始也说了,就是一开始假设不会造成数据冲突,在最后提交的时候再进行数据冲突检测。

在乐观锁中,我们有3种常用的做法来
实现。

[1]第一种就是在数据取得的时候把整个数据都copy到应用中,在进行提交的时候比对当前数据库中的数据和开始的时候更新前取得的数据。

当发现两个数据一模一样以后,就表示没有冲突可以提交,否则则是并发冲突,需要去用业务逻辑进行解决。

[2]第二种乐观锁的做法就是采用版本戳,这个在Hibernate中得到了使用。

采用版本戳的话,首先需要在你有乐观锁的数据库table上建立一个新的column,比如为number型,当你数据每更新一次的时候,版本数就会往上增加1。

比如同样有2个session同样对某条数据进行操作。

两者都取到当前的数据的版本号为1,当第一个session 进行数据更新后,在提交的时候查看到当前数据的版本还为1,和自己一开始取到的版本相同。

就正式提交,然后把版本号增加1,这个时候当前数据的版本为2。

当第二个session也更新了数据提交的时候,发现数据库中版本为2,和一开始这个session取到的版本号不一致,就知道别人更新过此条数据,这个时候再进行业务处理,比如整个Transaction都Rollback等等操作。

在用版本戳的时候,可以在应用程序侧使用版本戳的验证,也可以在数据库侧采用Trigger(触发器)来进行验证。

不过数据库的Trigger的性能开销还是比较的大,所以能在应用侧进行验证的话还是推荐不用Trigger。

[3]第三种做法和第二种做法有点类似,就是也新增一个Table的Column,不过这次这个column是采用timestamp型,存储数据最后更新的时间。

在Oracle9i以后可以采用新的数据类型,也就是timestamp with time zone类型来做时间戳。

这种Timestamp的
数据精度在Oracle的时间类型中是最高的,精确到微秒(还没与到纳秒的级别),一般来说,加上数据库处理时间和人的思考动作时间,微秒级别是非常非常够了,其实只要精确到毫秒甚至秒都应该没有什么问题。

和刚才的版本戳类似,也是在更新提交的时候检查当前数据库中数据的时间戳和自己更新前取到的时间戳进行对比,如果一致则OK,否则就是版本冲突。

如果不想把代码写在程序中或者由于别的原因无法把代码写在现有的程序中,也可以把这个时间戳乐观锁逻辑写在Trigger或者存储过程中。

相关文档
最新文档