关于J2EE中死锁问题的研究(1)

大多数重要的应用程序都涉及高度并发性和多个抽象层。并发性与资源争用有关,并且是导致死锁问题增多的因素之一。多个抽象层使隔离并修复死锁环境的工作变得更加困难。

  通常,当同时执行两个或两个以上的线程时,如果每个线程都占有一个资源并请求另一个资源,这时就会出现死锁情况。因为如果一个线程不能获取资源,则所有线程都不能继续执行,我们称那个特定的线程被阻塞;如果每个线程都由于同组中另一个线程所占有的资源而被阻塞,我们就称这个线程组被死锁。

  在本文中,我们将讨论发生在典型的重要J2EE应用程序中的两大类死锁情况:“简单”数据库死锁和跨资源死锁。虽然我们的讨论基于J2EE平台,但也适用于其他技术平台。

  数据库死锁

  在数据库中,如果一个连接占用了另一个连接所需的数据库锁,则它可以阻塞另一个连接。如果两个或两个以上的连接相互阻塞,则它们都不能继续执行,这种情况称为死锁。

  数据库死锁问题不易处理,这是因为涉及到的锁定通常不是显式的。通常,对数据行进行隐式更新时,需要锁定该数据行,执行更新,然后在提交或回滚封闭事务时释放锁。由于数据库平台、配置的隔离级以及查询提示的不同,获取的锁可能是细粒度或粗粒度的,它会阻塞(或不阻塞)其他对同一数据行、表或数据库的查询。

  获取的锁依赖于内部生成的查询计划。当数据大小和分步随时间发生变化时,该计划也可能改变。这样在一个环境中获取一组锁的查询可以尝试在另一个环境中获取一组完全不同的锁。必要时,数据库可以随意地增加它的锁。例如,数据库可能会选择锁定整页,而不是锁定同一数据页中的10个数据行,这会阻塞对无需锁定的数据行的读写权限。

  基于数据库模式,读写操作会要求遍历或更新多个索引、验证约束、执行触发器等。每个要求都会引入更多锁。此外,其他应用程序还可能正在访问同一数据库模式中的某些对象,并获取不同于您的应用程序所具有的锁。

  所有这些因素综合在一起,数据库死锁几乎不可能被消除了。值得庆幸的是,数据库死锁通常是可恢复的:当数据库发现死锁时,它会强制销毁一个连接(通常是使用最少的连接),并回滚其事务。这将释放所有与已经结束的事务相关联的锁,至少允许其他连接中有一个可以获取它们正在被阻塞的锁。

  由于数据库具有这种典型的死锁处理行为,所以当出现数据库死锁问题时,数据库常常只能重试整个事务。当数据库连接被销毁时,会抛出可被应用程序捕获的异常,并标识为数据库死锁情况。如果允许死锁异常传播到初始化该事务的代码层之外,则该代码层可以只启动一个新事务并重做先前所有工作。要正确使用此策略,则在事务成功提交之前,它的代码不能有其他操作。注意:要限制重试次数,否则易导致死锁的代码块会永久循环下去。

  如果出现问题就重试,这种方法有点笨。但是,由于数据库可以自由地获取锁,所以几乎不可能保证两个或两个以上的线程不发生数据库死锁。此方法至少能保证在出现某些罕见的数据库死锁情况时,应用程序能正常运行。这比要求用户去重试操作要好得多。

  在J2EE应用程序中,开发人员可以设置一个EJB调用以使用Bean托管事务(BMT)——开发人员启动、提交或回滚特定的事务或容器托管事务(CMT)——调用方法前启动事务,并在方法完成后提交或回滚事务。如果EJB供应商提供retry-on-deadlock参数,从而可以通过容器托管事务自动完成此操作,那当然再好不过了。如果没有这种自动功能,开发人员最终将仅为了对死锁进行重试而强制EJB调用使用Bean托管事务。

  遇到死锁问题和锁定其他线程的锁的具体频率在很大程度上取决于数据库平台、硬件、数据库模式和查询。在使用基于锁的并发控制的数据库(如MSSQL)中,未提交的写操作会阻止读操作,而未提交的读操作会阻止写操作,使数据库更易出现死锁问题。在多版本并发控制(MVCC)数据库(如Oracle)中,未提交的写操作不阻止读操作——读操作仅查看旧版本数据行。这虽然会引入其他问题,但不会造成同样多的死锁机会。我们要让自己熟悉这些数据库锁定模式,并注意自己正在使用的类型。

  在查找、修复以及避免数据库死锁方面,有一些很好的参考方法,但它们都不能彻底消除死锁的可能性。

  跨资源死锁

  当死锁情况不完全局限于数据库时,将更难找到它。数据库对占有和请求的锁有识别能力,所以能检测整个数据库中的死锁;此外,数据库事务在确定哪些东西是原子、哪些不是方面提供了一个良好的界线,所以能轻松地回滚事务,使其从死锁中恢复。其他环境(如Java虚拟机)中的死锁或可跨环境的死锁更加危险,因为环境不能(或没有)检测到这些死锁并尝试恢复。更糟糕的是,这些死锁会产生综合效果——如果两个线程占有某些资源集时出现死锁,则其他任何尝试访问其中一个资源的线程也将被阻塞,该线程已经获取的所有资源也被阻塞。这些死锁常常不易发现,但对常见模式有一定的了解将有助于识别和修复死锁问题。

  当环境中出现可疑的死锁情况时,您就需要考虑一些问题了。这些问题的答案将说明您正在处理的情形是下列情形中的哪一种(如果有的话),并提供了修复以下问题的详细信息。要考虑的一些重要事项包括:
  • 涉及什么线程,它们的调用堆栈是什么?这需要进行一些详细的分析,将实际的死锁线程从那些只是被死锁的线程阻塞了的线程中分离出来。
  • 这种死锁情况总是在特定的代码路径中出现(每次执行这些特定的操作时),还是依赖于两个或两个以上同时执行的代码路径呢?
  • 涉及的数据库连接是什么?每个连接占有的数据库锁是什么?每个连接尝试获取的数据库锁是什么?每个数据库连接响应的Java虚拟机线程是什么?
  下一小节介绍了三种常见的发生跨资源死锁的情形。

转载于:https://www.cnblogs.com/xiefang1980/archive/2008/04/28/1174130.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/380050.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python变量分配内存_Python | 声明任何变量而不分配任何值

python变量分配内存Since, Python is a dynamic programming language so there is no need to declare such type of variable, it automatically declares when first time value assign in it. 由于Python是一种动态编程语言,因此无需声明此类变量,它…

UVA 10004 - Bicoloring

模拟染色&#xff0c;因为只有两种颜色&#xff0c;所以分别用 0、 1 代表这两种颜色&#xff0c;然后从0开始深搜&#xff0c;如果 每个点都能染上色&#xff0c;且相邻两点的颜色不同&#xff0c;则符合要求。 #include<stdio.h>#include<string.h>#define MAXN …

标志寄存器:CF、PF、AF、ZF、SF、TF、DF、OF

注&#xff1a;下面说到的标志寄存器都是缩写&#xff0c;C就是CF&#xff0c;其他也一样 标志寄存器&#xff1a;C、P、A、Z、S、T、D、O的内容只会是0或1&#xff0c;0表示假&#xff0c;1表示真 O&#xff1a;溢出标志 一个寄存器如果存放的值超过所能表示的范围&#xf…

揭秘:销售人员26个致命弱点

销售人员有许多积极的态度需要学习&#xff0c; 同时也有许多不良的习惯应该避免&#xff0c;以免影响个性及专业能力。仔细看看这些缺点&#xff0c;反省你自己&#xff0c;还需要改善的画&#xff0c;直到你给自己一百分为止。找一位深知你的好 友&#xff0c;让他诚实地给你…

Java——集合(练习题)

例题1&#xff1a;产生10个1~20之间的随机数&#xff0c;要求随机数不能重复 import java.util.HashSet; import java.util.Random; public class Test1 {/*** 产生10个1~20之间的随机数&#xff0c;要求随机数不能重复* * 分析&#xff1a;* 1,有Random类创建随机数对象* 2&a…

模块化 组件化 工程化_软件工程中的模块和软件组件

模块化 组件化 工程化The module in software is a small part of the software that is responsible for performing any kind of functionality. Sometimes, the term sub-program is also used to refer to the term module. 软件中的模块是软件的一小部分&#xff0c;负责…

Firefox2狂占CPU解决办法

https://images.cnblogs.com/cnblogs_com/Tisty/138006/o_firefox3.jpg 看了一下&#xff0c;不知道 "jpeg_free_large" 是干啥的&#xff0c;遂用 "Firefox jpeg_free_large" Google 一下&#xff0c;出来的一堆东西里有帖子说可能和 Apple 的 QuickTime …

PUSHAD和POPAD,以及PUSHA和POPA

PUSHAD PUSHAD也叫保护现场&#xff0c;就是把我们的寄存器压入栈中 pushad是把eax&#xff0c;ecx&#xff0c;edx&#xff0c;ebx&#xff0c;esp、ebp&#xff0c;esi&#xff0c;edi依次压入栈中&#xff0c;ESP会减少32&#xff0c;相当于&#xff1a; push eax push ec…

Java——n个数的全排列

例题&#xff1a; 输入一串字符串&#xff0c;将该字符串中的字符元素进行全排列&#xff0c;然后&#xff0c;一串输出结果。 例如&#xff1a; 输入&#xff1a; ABCD 输出&#xff1a; ABCD ABDC ACBD ACDB ADBC ADCB BACD BADC BCAD BCDA BDAC BDCA CABD CADB CBAD CBDA…

一段个性化stringgrid的代码

需要注意的是 该段程序使用了 canvas。 procedure TW_CkbTaiZhang.KhLstDrawCell(Sender: TObject; ACol,ARow: Integer; Rect: TRect; State: TGridDrawState);begin if ARowkhlst.Row then with khlst.Canvas do //画 cell 的边框 begin Pen.Color : $00ff0000; …

dp 扔鸡蛋_使用动态编程(DP)的鸡蛋掉落问题

dp 扔鸡蛋Problem statement: You are given N floor and K eggs. You have to minimize the number of times you have to drop the eggs to find the critical floor where critical floor means the floor beyond which eggs start to break. Assumptions of the problem: 问…

MOVSX和MOVZX

MOVSX 先符号扩展,再传送 格式&#xff1a; MOVSX 操作数A &#xff0c;操作数B //操作数B的空间小于A比如说我们使用命令&#xff1a; movsx eax&#xff0c;bxbx是16位&#xff0c;eax是32位&#xff0c;传值过程&#xff1a; 先用bx的符号位把eax高16填满&#xff0c;b…

统计学习以及支持向量机的国内外基本比较重要的书

1、支持向量机导论&#xff0c;此书乃是SVM方面的经典著作&#xff0c; 该书的作者也是近年来SVM、kernel methods学术圈内的活跃学者&#xff0c;对于这些领域均有过重要的贡献。这本书从“线性机器、核方法、统计学习理论、凸优化”四个方面揭示了SVM的内在机理 --利用核…

Java——集合(TreeSet)

package com.wsq.set; //这里进行调用Person()方法&#xff0c;要进行导包 import java.util.TreeSet; import com.wsq.bean.Person; public class Demo3_TreeSet { /*** TreeSet集合是用来对元素进行排序的&#xff0c;同样它也可以保证元素的唯一* 当compareTo()方法返…

setmonth_日期setMonth()方法以及JavaScript中的示例

setmonthJavaScript日期setMonth()方法 (JavaScript Date setMonth() method) setMonth() method is a Date class method, it is used to set the month to the Date object with a valid month value (between 0 to 11. 0 for January, 1 for February and so on). setMonth(…

LEA与XCHG

LEA 格式&#xff1a; LEA 通用寄存器 内存地址功能&#xff1a;取地址命令 将内存地址赋值给寄存器 lea eax,dword ptr ds:[ecx0x16]dword 双字 就是四个字节ptr pointer缩写 即指针ds 数据段版寄存器[]里的数据是一个地址值&#xff0c;这个地址指向一个双字型数据 将dwo…

分域名优化的时候要考虑备选IP的问题

我们在需要下载很多内容的时候&#xff0c;很容易想到做分域名的并发下载&#xff0c;给原来的服务器多分几个域名&#xff0c;因为分不同的域名可能可以在浏览器中分到更多的下载进程&#xff0c;提高下载速度。 但是在做网络应用的时候&#xff0c;我们的一个域名下面有的时候…

面试题-ASP 与 ASP.Net的区别?

比较简洁的回答&#xff1a; 1.开发语言不同&#xff0c;ASP局限于用脚本语言来开发&#xff0c;而ASP.Net可以使用C#,VB.C等来开发。 2.运行机制不同&#xff0c;ASP是解释运行的&#xff0c;执行效率较低。ASP.Net是编译性的编程框架。 3.开发方式不同&#xff0c;ASP里前台H…

Java——集合(输入5个学生的信息按总分高低排序)

题目要求&#xff1a; 键盘录入5个学生信息&#xff08;姓名&#xff0c;语文成绩&#xff0c;数学成绩&#xff0c;英语成绩&#xff09;&#xff0c;按照总分从高到低输出到控制台 分析&#xff1a; 1&#xff0c;定义一个学生类 * 成员变量&#xff1a;姓名&#xff0c;…

日期setHours()方法以及JavaScript中的示例

JavaScript Date setHours()方法 (JavaScript Date setHours() method) setHours() method is a Date class method, it is used to set the hour to the Date object with a valid hour value (between 00 to 23). setHours()方法是Date类方法&#xff0c;用于将小时设置为具有…