`
wang4674890
  • 浏览: 88958 次
  • 性别: Icon_minigender_2
  • 来自: 厦门
社区版块
存档分类
最新评论

Oracle 悲观锁和乐观锁

 
阅读更多

一.丢失更新
   
所有多用户环境中存在丢失更新,丢失更新可以如下示例:
   

        发生这种情况的原因:应用开发人员编写的程序时是这样的:更新一个特定的字段时,该记录的所有字段都会“刷新”(只是因为更新所有列更容易,这样就不用先得出哪些列已经修改,并且只更新那些修改过的列)。

       避免这种情况可以用两种锁定策略:悲观锁定或乐观锁定。

二.悲观锁
     
悲观锁定只用于有状态或有连接环境
     在试图更新之前,从数据库查询这一行就锁定这一行。
(因为我们很悲观,对于这一行能不能保持未改变很是怀疑)
  
  select empno,ename,sal from scott.emp where deptno=10;
  

EMPNO  ENAME   SAL
    7782    CLARK    2450.00
    7839    KING       5000.00
    7934    MILLER    1300.00


  在SQLplus中模拟应用可能执行的绑定调用,可以利用下面命名:
 SQL> variable empno number
SQL> variable ename varchar2(20)
SQL> variable sal number
SQL> exec :empno :=7934; :ename :='MILLER'; :sal :=1300;
 
PL/SQL procedure successfully completed


 for update 锁定这一行
 
The FOR UPDATE clause lets you lock the selected rows so that other users cannot lock or update the rows until you end your transaction. You can specify this clause only in a top-level SELECT statement, not in subqueries.
 
锁定命令:
 SQL>  select empno,ename,sal from scott.emp
  2  where empno=:empno and ename=:ename and sal=:sal
  3  for update nowait;

EMPNO ENAME            SAL
----- ---------- ---------
 7934 MILLER       1300.00

试图对这行进行修改
SQL>update scott.emp set ename='ML' where empno=7934;
进程耗在这,因为这行被你锁定了,在你结束你的事务之前,不能修改


查询锁定对象:
SELECT Do.Object_Name, Session_Id, Process, Locked_Mode
FROM V$locked_Object  Lo, Dba_Objects Do
WHERE Lo.Object_Id = Do.Object_Id;

OBJECT_NAM SESSION_ID PROCESS      LOCKED_MODE
  ----------            ----------            ------------           -----------
    EMP                 140                   3204:3008              3

提交事务,锁释放。之后可以进行更新


三.乐观锁
    乐观锁:把所有锁定都延迟到即将执行更新之前才做。换句话说,我们会修改信息而不需要锁。
  
(我们很乐观,认为数据不会被其他用户修改,因此,会等到最后一刻才去看想法对不对)

   实现乐观并发控制的有很多种;
(1)可以在应用中同时保留旧值和新值,然后再更新数据时使用如下语句,这是乐观锁的一种流行实现:
    update table
       set column1 =:new_column1, column2 =:new column2,...
    where primary_key=:primary_key
    and column1 =:old_column1
    and column2 =:old_column2
    ........
 
 
  (2)使用一个特殊的列记录的"版本",这个列由数据库触发器或应用程序代码维护。
 例子: (先建一个表,然后插入数据,在更新时如果实现乐观锁)
 create table carleena.dept
( deptno number(2),
  dname  varchar2(14),
  loc    varchar2(13),
  last_mod timestamp with time zone default systimestamp not null,
  constraint dept_pk primary key(deptno) 
)


插入数据
  insert into carleena.dept(deptno,dname,loc)
  select deptno,dname,loc
  from scott.dept;


进行相关变量的绑定
SQL> variable deptno number;
SQL> variable dname varchar2(14);
SQL> variable loc varchar2(13);
SQL> variable last_mod varchar2(50);
SQL> begin
  2    :deptno :=10;
  3   select dname,loc,last_mod
  4   into :dname,:loc,:last_mod
  5    from carleena.dept
  6  where deptno=:deptno;
  7  end;
  8  /
 PL/SQL procedure successfully completed


deptno    dname                loc              last_mod
  ----------    ----------            ---------              ---------- 
  10          ACCOUNTING  NEW YORK   06-3月 -10 08.55.35.609000 下午 +08:00

执行更新(最后一行执行一个非常重要的检查,以确保时间戳一样,last_mod值一样说明没有进行修改,可以更新)
  SQL> update carleena.dept
  2  set dname = 'AC',
  3  last_mod =systimestamp
  4  where deptno =:deptno
  5  and last_mod =to_timestamp_tz(:last_mod);
 
 1 row updated

执行上面相同逻辑的更新,但是last_mod仍然使用原来绑定的值,没有获取新的值,这时最后一行的值不匹配,故不能进行更新。
  SQL> update carleena.dept
  2  set dname = 'AC1',
  3  last_mod =systimestamp
  4  where deptno =:deptno
  5  and last_mod =to_timestamp_tz(:last_mod);

  0 rows updated

乐观锁定还有其他实现方法


四. 总结:


    注意:两个T1并不是指同一时刻,两个T2也一样不是指同一时刻。
   只是表示一个时间序列

分享到:
评论

相关推荐

    Java 中的悲观锁和乐观锁的实现

    悲观锁和乐观锁各有优缺点,选择哪种锁机制取决于具体的应用场景和需求。悲观锁适合数据修改频繁且对数据一致性要求较高的场景;而乐观锁适用于数据修改较少且并发量较大的场景。在实际应用中,可以根据具体情况灵活...

    Hibernate乐观锁和悲观锁分析

    Hibernate支持的悲观锁模式有`LockMode.UPGRADE`(对应SQL的`for update`)和`LockMode.UPGRADE_NOWAIT`(Oracle特有的,用于立即返回等待超时的结果)。 **乐观锁(Optimistic Locking)** 乐观锁则相对乐观,它...

    Hibernate的乐观锁与悲观锁

    **Hibernate**作为一种流行的Java持久层框架,提供了多种机制来处理并发控制问题,其中最常用的就是**乐观锁**和**悲观锁**。本文将详细介绍这两种锁的原理、应用场景以及如何在Hibernate中实现。 #### 二、悲观锁...

    hibernate的乐观锁和悲观锁

    ### Hibernate的乐观锁和悲观锁 #### 一、引言 在软件开发中,尤其是在涉及大量并发操作的应用场景下,确保数据的一致性和完整性是非常重要的。对于基于Java Web的应用而言,Hibernate作为一款流行的ORM框架,提供...

    hibernate乐观锁和悲观锁学习

    本文主要讨论的是Hibernate框架中两种锁机制的使用:乐观锁和悲观锁。 首先,让我们深入理解悲观锁(Pessimistic Locking)。悲观锁正如其名字所示,假设并发环境中数据会被频繁修改,所以在整个数据处理过程中,它...

    Hibernate实现悲观锁和乐观锁代码介绍

    Hibernate 实现悲观锁和乐观锁代码介绍 Hibernate 是一个基于 Java 的持久层框架,它提供了多种锁机制来实现事务的隔离性和一致性。在本文中,我们将详细介绍 Hibernate 实现悲观锁和乐观锁的代码实现,并讨论 ...

    Oracle的锁机制

    根据锁定时间,锁可分为悲观锁和乐观锁。悲观锁假设数据操作会发生冲突,所以在读取数据时立即锁定,例如表级锁。乐观锁则在数据更新时检查冲突,如行级锁,这样可以提高并发性能。 根据保护的对象,Oracle的锁分为...

    java调用Oracle的锁表命令

    - 考虑使用乐观锁或悲观锁策略,根据应用的并发需求选择合适的方式。 通过以上步骤,你可以在Java程序中安全有效地调用Oracle的锁表命令,确保数据一致性并优化并发性能。对于更复杂的应用场景,如分布式事务,...

    在分布式事务中实现基于Oracle PLSQL UL LOCK的悲观离线锁

    Oracle中的用户级(UL)锁就是一种悲观锁,它允许用户自定义锁机制,提供更细粒度的控制。 PL/SQL UL LOCK的实现通常涉及以下几个步骤: 1. **创建锁表**:首先,你需要创建一个表来存储锁定信息。这个表通常包含...

    查看Oracle锁表

    3. **并发控制机制**:如乐观锁和悲观锁等技术。 4. **定期检查锁定情况**:定期执行上述SQL查询,及时发现并解决锁定问题。 #### 五、总结 在Oracle数据库中,了解和掌握锁定机制对于确保数据完整性和提高系统...

    oracle锁表处理

    - **并发控制**:使用Oracle提供的并发控制机制,如乐观锁或悲观锁。 通过以上方法,可以有效地分析并处理Oracle中的锁争用问题,提高系统的性能和稳定性。需要注意的是,在实际操作中应当谨慎处理锁争用问题,...

    oracle 锁及并发性

    悲观锁和乐观锁是两种不同的并发控制策略。 - **悲观锁**:假设数据会发生冲突,因此在事务开始时即锁定数据,直到事务结束。这种方式虽然能有效避免冲突,但可能导致资源占用时间较长。 - **乐观锁**:假设数据...

    SQL数据库系统原理(二)———乐观锁与悲观锁、MVCC、范式理论、SQL和NoSQL比较

    在数据库系统中,为了保证数据的一致性和完整性,有多种并发控制策略,其中包括乐观锁和悲观锁。这两种锁机制主要用于解决事务在并发环境中的数据冲突问题。 乐观锁是一种假设事务在执行过程中不会发生冲突的策略。...

    ORACLE深入浅出-中级篇.pptx

    悲观锁可以使用 for update nowait 语句来加锁,而乐观锁可以通过增加标识列或使用 Oracle 的 ORA_ROWSCN 机制来实现。 阻塞与死锁 如果两个会话都持有另一个会话想要的资源,就会出现死锁。例如,可以打开两个...

    Oracle表死锁与解锁

    - 在编程时,对可能出现死锁的操作进行预测和处理,例如使用事务的乐观锁或悲观锁策略。 通过理解Oracle表死锁的原理、使用上述检测和解决方法,以及遵循最佳实践,可以有效地管理和防止数据库死锁,保证系统的稳定...

    oracle 锁

    - **乐观锁**:假设很少发生冲突,因此在提交事务时检查是否有冲突,如版本控制或时间戳。 - **悲观锁**:在访问数据时立即锁定,防止其他用户修改,适合高冲突环境。 4. **锁定级别**: - **多粒度锁定...

    oracle锁讲解笔记

    Oracle中的锁主要分为三类:DML锁、DDL锁和内部锁(LATCH)。DML锁又细分为表级锁(TM)和行级锁(TX)。 - **表级锁(TM)**:用于保护表级别的操作,防止DDL语句的执行。 - **行级锁(TX)**:用于保护行级别的...

    oracle锁机制

    Oracle数据库的锁又细分为不同的类别,如DML锁(数据锁)、DDL锁(字典锁)以及内部锁和闩。DML锁主要用于确保数据操作时的完整性,其中TM锁(表级锁)和TX锁(事务锁或行级锁)是核心部分。TM锁在事务开始时获取,...

Global site tag (gtag.js) - Google Analytics