在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(即S锁)。当数据对象被加上排它锁时,其他的事务不能不 
能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两种基本的锁类型来对数据库的事务进行并发 
控制。

死锁的第一种情况:

一个用户A访问表A(锁住了表A),然后又访问表B; 另一个用户B访问表B(锁住了表B),然后企图访问表A;这时用户A由于用户B已经锁住 
表B,它必须等待用户B释放表B才能继续,同样用户B要等用户A释放表A才能继续,这就死锁产生了。

解决方法:

这种死锁比较常见,是由于程序的BUG产生的,除了调整程序的逻辑没有其它的办法。仔细分析程序的逻辑,对于数据库的多表操作时,尽量 
按照同样的顺序进行处理,尽量避免同时锁定两个资源,如操作A和B两张表时,总是按先A后B的顺序处理,必须同时锁定两个资源时,要保 
证在任何时刻都应该按照相同的顺序来锁定资源。

死锁的第二种情况

用户A查询一条记录,然后修改该条记录;这时用户B修改该条记录,这时用户A的事务里锁的性质由查询的共享锁企图上升到独占锁,而用户 
B里的独占锁由于A有共享锁存在必须等A释放掉共享锁,而A由于B的独占锁而无法上升到独占锁也就不可能释放共享锁,于是出现了死锁。这 
种死锁比较隐蔽,但在稍大点的项目种经常发生,如在某项目中,页面上的按钮点击后,没有使按钮立刻失效,使得用户会多次快速点击同 
一按钮,这样同一段代码对数据库同一条记录进行多次操作,很容易就出现这种死锁的情况。

解决方法:

1、对于按钮等控件,点击后使其立刻失效,不让用户重复点击,避免对同时对同一条记录操作。

2、使用乐观锁进行控制。乐观锁大多是基于数据版本(version)记录机制实现。即为数据增加一个版本标识,在基于数据库表的版本解决 
方案中,一般是通过为数据库增加一个“version”字段来实现。读取处数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时, 
将提交的数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否 
则认为是过期数据。乐观锁机制避免了长事务中的数据库加锁开销(用户A和用户B操作过程中,都没有对数据库加锁),大大提升了大并发 
量下的系统整体性表现。 Hibernate在其数据访问引擎中内置了乐观锁实现。需要注意的是,由于乐观锁机制是我们的系统中实现,来自外 
部系统的用户更新操作不受我们系统的控制,因此可能会造成脏数据被更新到数据库中。

3、使用悲观锁进行控制。悲观锁大多数情况下依靠数据库的锁机制实现,如Oracle的select.......for update语句,以保证操作最大程度 
的独占性。但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。如一个金融系统,当某个操作员读 
取用户的数据,并在读出的用户数据的基础上进行修改时(如更改用户帐户余额),如果采用悲观锁机制,也就意味整个操作过程中(从操 
作员读出数据、开始修改直至提交修改结果的全过程,甚至还包括操作员中途去煮咖啡的时间),数据库记录始终处于加锁状态,可以想见 
,如果面对成百上千个并发,这样的情况将导致灾难性的结果。所以,采用悲观锁进行控制时一定要考虑清楚。

死锁的第三种情况

如果在事务种执行了一条不满足条件的update语句,则执行全表扫描,把行级锁上升为表级锁,多个这样的事务执行之后,就很容易发生死 
锁和阻塞。类似的情况还有当表种的数据量非常庞大而索引建的过少或不合适的时候,使得经常发生全表扫描,最终应用系统会越来越慢, 
最终发生阻塞或死锁。

解决方法:

SQL语句中不要使用太复杂的关联多表的查询;使用“执行计划”对SQL语句进行 分析,对于有全表扫描的SQL语句,建立相应的索引进行优化

Oracle中死锁与等待的更多相关文章

  1. ORACLE中死锁

    ORACLE中死锁的知识点总结   死锁的概念 什么是死锁呢? 其实我们生活中也有很多类似死锁的例子. 我先举一个生活中的例子:过年回家,父亲买了一把水弹枪,儿子和侄子争抢着要先玩,谁也不让谁,拆开包 ...

  2. ORACLE中死锁的知识点总结

      死锁的概念 什么是死锁呢? 其实我们生活中也有很多类似死锁的例子. 我先举一个生活中的例子:过年回家,父亲买了一把水弹枪,儿子和侄子争抢着要先玩,谁也不让谁,拆开包装后,一个抢了枪, 一个逮住了子 ...

  3. Oracle中常见的33个等待事件小结

    在Oracle 10g中的等待事件有872个,11g中等待事件1116个. 我们可以通过v$event_name 视图来查看等待事件的相关信息     一. 等待事件的相关知识 1.1 等待事件主要可 ...

  4. .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况

    一个简单的 Task 不会消耗多少时间,但如果你不合适地将 Task 转为同步等待,那么也可能很快耗尽线程池的所有资源,出现类似死锁的情况. 本文将以一个最简单的例子说明如何出现以及避免这样的问题. ...

  5. 【Java并发基础】使用“等待—通知”机制优化死锁中占用且等待解决方案

    前言 在前篇介绍死锁的文章中,我们破坏等待占用且等待条件时,用了一个死循环来获取两个账本对象. // 一次性申请转出账户和转入账户,直到成功 while(!actr.apply(this, targe ...

  6. [转]Oracle中INITRANS和MAXTRANS参数

    每个块都有一个块首部.这个块首部中有一个事务表.事务表中会建立一些条目来描述哪些事务将块上的哪些行/元素锁定.这个事务表的初始大小由对象的INITRANS 设置指定.对于表,这个值默认为2(索引的IN ...

  7. oracle中事务处理

    事务用于保证数据的一致性,它由一组相关的dml语句组成,该组的dml语句要么全部成功,要么全部失败. 事务和锁 当执行事务操作时(dml语句),oracle会在被作用的表上加锁,防止其它用户改表的结构 ...

  8. ORACLE 中的 锁 介绍

    ORACLE 中的 锁 介绍 Oracle数据库支持多个用户同时与数据库进行交互,每个用户都可以同时运行自己的事务,从而也需要对并发访问进行控制.Oracle也是用“锁”的机制来防止各个事务之间的相互 ...

  9. 【Oracle】浅析Oracle中的事务

    1. 什么是事务 在数据库中事务是工作的逻辑单元,一个事务是由一个或多个完成一组的相关行为的SQL语句组成,通过事务机制确保这一组SQL语句所作的操作要么都成功执行,完成整个工作单元操作,要么一个也不 ...

随机推荐

  1. Java之List排序出错

    Java之List排序出错 Bound mismatch: The generic method sort(List<T>) of type Collections is not appl ...

  2. Java之split方法

    Java之split方法 1.间隔号"." (1)str.split(".") String str = "10.156.35.87"; S ...

  3. stl string 容器的使用

    string 是基本的字符串序列容器,对应数据结构中的串,和vector<char>也类似,但功能更多 string 容器的使用 1,string 的构造函数是. string() 2,s ...

  4. Error Code: 1414. OUT or INOUT argument 2 for routine company.new_procedure is not a variable or NEW

    1.错误描述 16:27:36 call new_procedure(20150112,1) Error Code: 1414. OUT or INOUT argument 2 for routine ...

  5. hi3531的pcie atu资源重映射

    1. 设置ATU 区域号寄存器为需要配置的地址转换区编号. 2. 设置ATU Region Lower Base Address Register 和ATU Region Upper Base Add ...

  6. LINQ 按多个字段排序(orderby、thenby、Take)

    LINQ 按多个字段排序(orderby.thenby.Take) orderby  子句解析为 OrderBy()方法,orderby descending 子句解析为OrderBy Descend ...

  7. GetBitmapFromScreen

    int GetBitmapFromScreen() { char *lpBuf; HBITMAP hBitmap,hOld ; HDC hDC,hcDC; BITMAP bb;BITMAPINFO b ...

  8. 多线程之倒计时器CountDownLatch和循环栅栏CyclicBarrier

    1.倒计时器CountDownLatch CountDownLatch是一个多线程控制工具类.通常用来控制线程等待,它可以让一个线程一直等待知道计时结束才开始执行 构造函数: public Count ...

  9. 说说你对用SSH框架进行开发的理解

    SSH框架指的是Struts,Spring,Hibernate.其中,Struts主要用于流程控制:Spring的控制反转能祈祷解耦合的作用:Hibernate主要用于数据持久化.

  10. 第一节 JDK是什么?JRE是什么?JDK和JRE的区别?以及jdk安装和测试。

    Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承.指针等概念,因此Java语言具有功能强大和简单易用两个特征.Java语言作为静态面向对象编程语言的代表 ...