DB2死锁的解决过程全记录_DB2

来源:脚本之家  责任编辑:小易  

SQLSTATE 42601:字符、标记或子句无效或丢失。我把你的语句在我本地DB2做了一遍,修改了一下,没有问题。我执行的语句:db2"insert into t_zm_dhyc(ID,COMPANYID,DEPTID,WEEK,STARTWEEK,ENDWEEK,EXECUTOR,EXECUTIONTIME,KHMC,KHDZ,XKZH,PPMC,SZDH,BZDH,HQB,YY,TXRID,TXRMC,TXSJ,STATUS,REMARK,TAG,TAG2)with t1 as(select COMPANYID,DEPTID,ORDERID,PRODUCTCODE,QUANTREQ qzsl,ISCANCEL from T_VISITSALES_ORDERDETAIL where ORDERDATE='1' and productid='1'),t2 as(select QUANTREQ bzsl from T_VISITSALES_ORDERDETAIL where ORDERDATE='1' and productid='1')select distinct '1' id,t1.COMPANYID,t1.DEPTID,'1' week,'2' startweek,'2' endweek,'' executor,'2' executiontime,'' khmc,'' khdz,'' xkzh,t1.PRODUCTCODE,t1.qzsl,t2.bzsl,t2.bzsl|t1.qzsl hqb,'' yy,'1' txrid,'' txrmc,'2' txsj,'0' status,'' remark,'' tag,'' tag2 from t1,t2查询结果:ID COMPANYID DEPTID WEEK STARTWEEK ENDWEEK EXECUTOR EXECUTIONTIME KHMC KHDZ XKZH PPMC SZDH BZDH HQB YY TXRID TXRMC TXSJ STATUS REMARK TAG TAG2-1-1 2 2 2-1 2 0 1 条记录已选择。为了方便检查,我将所有表字段都设置为char(1)了。从错误代码来看,请你检查一下数据库里面这两张表是否有齐你select或where的字段www.zgxue.com防采集请勿采集本网。

生产环境里使用的数据库是DB2。但是最近频繁出现一个奇怪的死锁现象:某一个select sql 语句总是会出现死锁。

并发操作带来了数据的不一致性: 主要有三种: 计算机系统中,如果系统的资源分配策略不当,更常见的可能是程序员写的程序有错误等,则会导致进程因竞争资源不当而产生死锁的现象。

按照以往的经验,通常都是update/delete之类的更新sql语句会出现死锁的问题。而且这个 select sql 语句是一个很普通的sql,没有任何大数据量的处理。

在系统中已经出现死锁后,应该及时检测到死锁的发生,并采取适当的措施来解除死锁。死锁预防。这是一种较简单和直观的事先预防的方法。方法是通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个

分析这个死锁,有很多难以处理的地方。

我觉得方法总比困难多,一定要学会寻找方法

1、因为生产环境数据量大,我们无法把生产环境中关联表的数据导入到测试环境。也就是说,无法模拟数据量。

12345的流程: 一、受理 接线人对各类诉求进行登记,转交交办处理组(接线受理人员当即解答除外)。二、办理 交办处理人拿出拟交办意见,交热线办分管副主任签发具体拟办意见。1、直办 对咨询性

2、没有任何log输出。因为生产环境的log输出级别是ERROR。

根据你的问题: 答复如下:1.索引只是解决查询效率问题,和锁没什么关系。2.如果插入表2时,表2有一条和当前插入的值相同,会产生主键冲突,你怎么处理?其实不知道你想解决什么问题。

3、无法在生产环境进行测试,因为客户不允许。

4、生产环境的数据库无法开启快照等功能。因为会影响性能。

大家可以想象,在没有快照等功能下,分析死锁就只能靠分析代码了。但是这个处理非常复杂,单凭分析代码,没有任何头绪。

 

阶段1:我们怀疑是数据量的原因

 

由于生产环境的数据量特别大,这个处理还有很多其他表的处理。所以我们怀疑是不是大数据量导致系统负荷过高,导致了死锁?

于是我们取得了发生死锁时CPU,硬盘,网络等等负载信息。没有找到任何线索。

 

阶段2:做一个测试程序,在测试环境中用多线程模拟多用户去做这个处理。

 

为了能够在开发环境再现出这个死锁,我们做了一个多线程的测试程序,模拟多用户运行。可惜,还是没有再现出来。

 

阶段3:分析测试环境数据库和产品环境数据库的差异

 

此时我们怀疑还是数据量导致的问题。于是我们尽可能的将开发环境的数据弄得和产品环境一样多。

之后在运行测试,还是没有再现出来。

 

阶段4:分析用户的操作log

 

没有任何办法的情况下,我们只好分析用户的操作log,希望从中找到一点线索。功夫不负有心人,我们发现,当两个人同时

进行这个操作的时候,基本都会发生死锁。所以,我们判断还是两个人同时操作导致的问题。但是,为什么开发环境上模拟了

很多人的操作,却没有发生死锁呢?

 

阶段5:发现数据库设置的问题

 

我们又修改了测试程序,将模拟的用户数量提高,但是很不幸,仍然没有再现这个问题。此时我们注意到了:是不是开发环境的

数据库设置和产品环境的数据库设置不同?我们对比了一下两个数据库的设置:发现好多参数不同。但是我们仅仅关注了和锁有关

的设置,也就是包含 LOCK关键字的设置。

 

阶段6:将测试环境数据库和产品环境数据库的设置保持一致

 

我们将所有和lock有关的设置都改成了和产品环境一直。但是仍然没有再现这个死锁。终于,一个人发现,"cur_commit"这个设置

不同。于是查询文档,发现了 cur_commit的特点。

当 cur_commit = false的时候,下列情况会造成死锁:

线程1插入数据A,然后线程2插入数据B。

在线程2还没有提交事物之前,线程1查询数据A,就会造成死锁了。

开发环境中,cur_commit = true,所以我们一直也模拟不出来这个现象。

于是,我们把cur_commit也改成了 false。

 

阶段7:使用测试程序去模拟

 

我们修改了测试程序,模拟上面两个线程的操作,成功地再现了这个死锁。错误的log信息和产品环境上也是一致的。

 

阶段8:使用画面操作去模拟

 

然后我们修改了程序,使用画面去操作,也成功地再现了这个死锁。

 

解决方案:

 

解决方案很简单,就是把查询语句中的条件加为索引,就不会出现死锁了。

由于这个表数据量不大,所以性能几乎没有任何影响。

JAVA中几种常见死锁及对策:解决死锁没有简单的方法,这是因为线程产生死锁都各有各的原因,而且往往具有很高的负载。大多数软件测试产生不了足够多的负载,所以不可能暴露所有的线程错误。在这里中,下面将讨论开发过程常见的4类典型的死锁和解决对策。(1)数据库死锁在数据库中,如果一个连接占用了另一个连接所需的数据库锁,则它可以阻塞另一个连接。如果两个或两个以上的连接相互阻塞,则它们都不能继续执行,这种情况称为数据库死锁。数据库死锁问题不易处理,通常数据行进行更新时,需要锁定该数据行,执行更新,然后在提交或回滚封闭事务时释放锁。由于数据库平台、配置的隔离级以及查询提示的不同,获取的锁可能是细粒度或粗粒度的,它会阻塞(或不阻塞)其他对同一数据行、表或数据库的查询。基于数据库模式,读写操作会要求遍历或更新多个索引、验证约束、执行触发器等。每个要求都会引入更多锁。此外,其他应用程序还可能正在访问同一数据库模式中的某些对象,并获取不同应用程序所具有的锁。所有这些因素综合在一起,数据库死锁几乎不可能被消除了。值得庆幸的是,数据库死锁通常是可恢复的:当数据库发现死锁时,它会强制销毁一个连接(通常是使用最少的连接),并回滚其事务。这将释放所有与已经结束的事务相关联的锁,至少允许其他连接中有一个可以获取它们正在被阻塞的锁。由于数据库具有这种典型的死锁处理行为,所以当出现数据库死锁问题时,数据库常常只能重试整个事务。当数据库连接被销毁时,会抛出可被应用程序捕获的异常,并标识为数据库死锁。如果允许死锁异常传播到初始化该事务的代码层之外,则该代码层可以启动一个新事务并重做先前所有工作。当出现问题就重试,由于数据库可以自由地获取锁,所以几乎不可能保证两个或两个以上的线程不发生数据库死锁。此方法至少能保证在出现某些数据库死锁情况时,应用程序能正常运行。(2)资源池耗尽死锁客户端的增加导致资源池耗尽死锁是由于负载而造成的,即资源池太小,而每个线程需要的资源超过了池中的可用资源。假设连接池最多有10个连接,同时有10个对外部并发调用。这些线程中每一个都需要一个数据库连接用来清空池。现在,每个线程都执行嵌套的调用。则所有线程都不能继续,但又都不放弃自己的第一个数据库连接。这样,10个线程都将被死锁。研究此类死锁,会发现线程存储中有大量等待获取资源的线程,以及同等数量的空闲且未阻塞的活动数据库连接。当应用程序死锁时,如果可以在运行时检测连接池,就能确认连接池实际上已空。修复此类死锁的方法包括:增加连接池的大小或者重构代码,以便单个线程不需要同时使用很多数据库连接。或者可以设置内部调用使用不同的连接池,即使外部调用的连接池为空,内部调用也能使用自己的连接池继续。(3)单线程、多冲突数据库连接死锁对同一线程执行嵌套的调用有时出现死锁,此情形即使在非高负载系统中通常也会发生。当第一个(外部)连接已获取第二个(内部)连接所需要的数据库锁,则第二个连接将永久阻塞第一个连接,并等待第一个连接被提交或回滚,这就出现了死锁情形。因为数据库没有注意到两个连接之间的关系,所以数据库不会将此情形检测为死锁。这样即使不存在并发,此代码也将导致死锁。此情形有多种具体的变种,可以涉及多个线程和两个以上的数据库连接。(4)Java虚拟机锁与数据库锁冲突这种情形发生在数据库锁与Java虚拟机锁并存的时候。在这种情况下,一个线程占有一个数据库锁并尝试获取Java虚拟机锁。同时,另一个线程占有Java虚拟机锁并尝试获取数据库锁。此时,数据库发现一个连接阻塞了另一个连接,但由于无法阻止连接继续,所以不会检测到死锁。Java虚拟机发现同步的锁中有一个线程,并有另一个尝试进入的线程,所以即使Java虚拟机能检测到死锁并对它们进行处理,它还是不会检测到这种情况。总而言之,JAVA应用程序中的死锁是一个大问题—它能导致整个应用程序慢慢终止,还很难被分离和修复,尤其是当开发人员不熟悉如何分析死锁环境的时候。五.死锁的经验法则笔者在开发中总结以下死锁问题的经验。(1)对大多数的Java程序员来说最简单的防止死锁的方法是对竞争的资源引入序号,如果一个线程需要几个资源,那么它必须先得到小序号的资源,再申请大序号的资源。可以在Java代码中增加同步关键字的使用,这样可以减少死锁,但这样做也会影响性能。如果负载过重,数据库内部也有可能发生死锁。(2)了解数据库锁的发生行为。假定任何数据库访问都有可能陷入数据库死锁状况,但是都能正确进行重试。例如了解如何从应用服务器获取完整的线程转储以及从数据库获取数据库连接列表(包括互相阻塞的连接),知道每个数据库连接与哪个Java线程相关联。了解Java线程和数据库连接之间映射的最简单方法是向连接池访问模式添加日志记录功能。(3)当进行嵌套的调用时,了解哪些调用使用了与其它调用同样的数据库连接。即使嵌套调用运行在同一个全局事务中,它仍将使用不同的数据库连接,而不会导致嵌套死锁。(4)确保在峰值并发时有足够大的资源池。(5)避免执行数据库调用或在占有Java虚拟机锁时,执行其他与Java虚拟机无关的操作。最重要的是,多线程设计虽然是困难的,但在开始编程之前详细设计系统能够帮助你避免难以发现死锁的问题。死锁在语言层面上不能解决,就需要一个良好设计来避免死锁内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • 数据库触发器db2和sqlserver有哪些区别
  • centos下db2数据库安装过程详解
  • db2数据库常用操作命令大全
  • db2新手使用的一些小笔记:新建实例、数据库路径不存在、客户端连接 .
  • db2 导入导出单个表的操作详解
  • db2比较常用与实用sql语句总结
  • db2 常用命令小结
  • db2 常用命令速查(备忘)
  • db2 日期和时间的函数应用说明
  • 详解db2 sqlstate 57016 sqlcode=-668 原因码 "7"错误的快速解决办法
  • db2 9数据服务器发展3部曲
  • ibm db2 日常维护汇总(六)
  • db2 9(viper)快速入门
  • db2中reverse函数的实现方法
  • ibm db2 日常维护汇总(二)
  • ibm db2 日常维护汇总(八)
  • db2常用傻瓜问题1000问(五)
  • db2 日期和时间的函数应用说明
  • db2数据库中常见的堵塞问题分析与处理方法
  • 对比db2 9和db2 v8.x中的xml功能
  • java线程死锁有几种解决方法
  • DB2 SQL error: SQLCODE: -104, SQLSTATE: 42601, SQLERRMC
  • SQL 进程死锁
  • 简化资源分配图 判断是否死锁 大神求教 求分析
  • 并发控制、冲突解决、死锁
  • 避免死锁的方法有哪些?
  • 阅读文章过程中,遇到不懂的问题,有哪些解决的方法? 请列举出来。
  • 12345的流程是什么
  • 数据表死锁 有两个表 结构都是一样的 主键设置也相同 写了一个存储过程,
  • 索赔的最终解决是什么?
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全mssqlmysqlmariadboracledb2mssql2008mssql2005sqlitepostgresqlmongodbredisaccess数据库文摘数据库其它首页db2数据库触发器db2和sqlserver有哪些区别centos下db2数据库安装过程详解db2数据库常用操作命令大全db2新手使用的一些小笔记:新建实例、数据库路径不存在、客户端连接 .db2 导入导出单个表的操作详解db2比较常用与实用sql语句总结db2 常用命令小结db2 常用命令速查(备忘)db2 日期和时间的函数应用说明详解db2 sqlstate 57016 sqlcode=-668 原因码 "7"错误的快速解决办法db2 9数据服务器发展3部曲ibm db2 日常维护汇总(六)db2 9(viper)快速入门db2中reverse函数的实现方法ibm db2 日常维护汇总(二)ibm db2 日常维护汇总(八)db2常用傻瓜问题1000问(五)db2 日期和时间的函数应用说明db2数据库中常见的堵塞问题分析与处理方法对比db2 9和db2 v8.x中的xml功能db2 常用命令小结db2数据库的备份和恢复db2优化(简易版)ibm db2 日常维护汇总(一)db2数据库的安装db2常用傻瓜问题1000问(一)db2比较常用与实用sql语句总结db2数据同步方面的经验db2常用傻瓜问题1000问(四)db2个人版(linux)安装db2 常用命令小结db2 9产品说明书在线参考地址(http)db2数据库中常见的堵塞问题分析与处理方法jsp如何连接db2数据库db2编程序技巧 (一)db2 9(viper)快速入门db2中reverse函数的实现方法db2编程序技巧 (三)db2编程序技巧 (五)如何安装sql server 2008 management stu
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved