CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
花落谁家,你作主! 盛大widget设计大赛英雄榜
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  其他数据库开发 >  SQL Anywhere Studio

oracle多线程死锁问题,散分~~~~~~~~

楼主superrg(秀华)2002-01-11 10:43:47 在 其他数据库开发 / SQL Anywhere Studio 提问

程序流程描述如下:  
  1.程序初始化时建立连接,进入主线程2;  
          2.主线程:  
              等待信号量event1(锁定数据库连接);  
              选择一条符合条件的记录idn;  
              如果idn不存在,则设置信号量event1(解除数据库连接锁定),并退出主线程,顺序执行到4;  
              用update把记录idn作已选择标记;  
              设置信号量event1(解除数据库连接锁定);  
              创建子线程3,带入的结构参数值为idn,子线程数加一(采用锁定加一法);  
            4.等待所有子线程结束;  
                断开数据库连接;  
                程序正常退出;  
                          3.子线程:(入口结构参数为idn)  
                                等待信号量event1;  
                                锁定数据库连接;  
                                选择idn记录的相关信息,并保存在变量中;  
                                解除数据库连接锁定;  
                                设置信号量event1;  
                                打印idn记录的相关信息;  
                                子线程数减一(采用锁定减一法)  
                                如果子线程数为零,则设置所有子线程结束信号量;  
                                结束子线程;  
   
  问题描述如下:  
  如果把3.子线程中的数据库操作部分去掉,而直接打印idn值,则程序可以从主线程成功创建子线程,并且所有的线程(主线程、子线程)都能正常结束;但如果加入了数据库操作的部分,则主线程在他建了约三百个子线程后就一直处于等待状态(不再创建子线程),看样子好像是死锁了;  
  在3.子线程中,打印函数是用互斥信号来控制打印的开始与结束的,因此系统在这里也有可能发生死锁;  
   
  csdn最高只允许本人出300分,想要分的可以另外想办法送,帮本人把这个死锁(或其它解决办法)找出来,就可以拿到分了。  
   
  本程序调试环境:P4(1.4)   +   1G   +   win2ksp2   +   o9i   +   pro   c++   +   vc6.0,有请在多线程数据库操作有丰富经验的高手指教,谢谢~~~~~  
    问题点数:300、回复次数:36Top

1 楼superrg(秀华)回复于 2002-01-11 11:16:23 得分 0

惨了,怎么我的贴子没有人回也没有人看呀???高手在哪里呀,高手在哪里????Top

2 楼superjj2002(小鸟)回复于 2002-01-11 12:30:45 得分 20

帮你抬一下,:)Top

3 楼flowerofwind(现实很残酷)回复于 2002-01-11 12:41:55 得分 20

你们俩的名字还有点相似哦Top

4 楼flowerofwind(现实很残酷)回复于 2002-01-11 12:43:44 得分 50

子线程中的数据库操作部分去掉,而直接打印idn值,则程序可以从主线程成功创建子线程,并且所有的线程(主线程、子线程)都能正常结束;但如果加入了数据库操作的部分,则主线程在他建了约三百个子线程后就一直处于等待状态(不再创建子线程),  
  这时候数据库操作有没有返回什么错误代码?Top

5 楼superrg(秀华)回复于 2002-01-11 12:49:07 得分 0

to   superjj2002():  
  thanks...  
  to   flowerofwind(现实很残酷):  
  由于屏幕打印太快了,没有看清有没有错误,难道如果有错误,程序就会一直等待吗???  
  我在程序中设置了oracle错误处理程序的呀~~~~~~~  
  Top

6 楼KingSunSha(弱水三千)回复于 2002-01-11 13:14:46 得分 0

把执行结果SPOOL去一个文件跟踪吧,这样查起来方便一点Top

7 楼superrg(秀华)回复于 2002-01-11 13:30:50 得分 0

to   KingSunSha(弱水三千):  
  把所有的结果都放入spool文件中吗??成千上万个线程的结果,到时候怎么看好呢????Top

8 楼KingSunSha(弱水三千)回复于 2002-01-11 14:05:25 得分 0

当然不可能跟踪所有的信息,在程序执行的关键点和EXCEPTION上加入OUTPUT,或者逐步的加入,用排除法逐步缩小错误的范围。  
  大概也只能这样了Top

9 楼superrg(秀华)回复于 2002-01-11 14:55:02 得分 0

to   KingSunSha(弱水三千):  
  但是所有子线程的程序都是一样的呀,我也不知道到时候是锁死在子线程还是在主线程呀,如果不是全加,跟没有加是一样的呀~~~~~Top

10 楼cmszzx()回复于 2002-01-11 15:53:45 得分 20

帮你推一推Top

11 楼KingSunSha(弱水三千)回复于 2002-01-11 16:12:17 得分 0

有难度,让我想一想Top

12 楼aimi0123456(艾米)回复于 2002-01-11 16:17:37 得分 20

真的能散到分?爽!Top

13 楼Haiwer(海阔天空)回复于 2002-01-11 16:24:03 得分 20

三千兄在想了,看来能解决!  
   
  我是来学习的!  
  Top

14 楼mycode(不写代码)回复于 2002-01-11 17:18:29 得分 20

你对数据库的操作是通过几个Connection来实现的.  
  Connection是一直存在还是即用即建.  
  个人觉得,访问数据库的操作,还是通过中间件服务器,如MTS或Tuxedo去实现.会较大的提高系统的稳定性.  
  Top

15 楼superrg(秀华)回复于 2002-01-11 17:35:24 得分 0

to   mycode(不写代码):  
  只用了一个connection,用event1信号量控制数据库操作的,但是用中间件去实现的速度明显慢得多了~~~~~~  
  to   KingSunSha(弱水三千):  
  赁你多年的数据库经验,究竟是什么原因锁住了???  
  to   others:  
  Thanks   a   lot...  
  Top

16 楼mycode(不写代码)回复于 2002-01-11 17:45:34 得分 30

用update把记录idn作已选择标记;  
  为什么要这样用?  
  有没有可能是你的其他程序锁住了某条记录,导致你的程序遇上这条记录时,死锁,并且刚好出现在大约300条记录上.  
  出现死锁时,检查一下此时的数据库,是否出现死锁,以确定是否是数据库的操作出现死锁.  
   
  应用程序本身的结构,是否没有什么问题.  
  Top

17 楼superrg(秀华)回复于 2002-01-11 17:53:28 得分 0

to   mycode(不写代码):  
  用update把记录idn作已选择标记的原因是:每个线程只处理一条记录,相当于游标的作用,如果不作标记,则下一次主线程产生子线程时就会重复地选择这一条记录了;而不使用游标的原因是因为整个表的数据都是动态的,子线程处理后有可能往这个表中加入新的数据;程序测试时只有我一个人在用这个测试库,如果说其它程序锁住了某条记录,则只能说是oracle系统锁住了,至于锁的原因,我就找不出来了~~~~~~晚上我再打开管理器看看有没有锁,如果没有锁就更难调了~~~~Top

18 楼KingSunSha(弱水三千)回复于 2002-01-11 18:06:10 得分 100

刚学了一些java中线程的运行原理,说实话不是很清楚。  
   
  记得书上讲到最容易发生死锁的情况是这样的:  
  session1   update(or   lock)   table1;  
  session2   update(or   lock)   table1;  
  session2   update(or   lock)   table2;  
  session1   update(or   lock)   table2;  
  session1.commit  
  session2.commit  
   
  这种情况下两个session相互等待对方commit完成,形成死锁。  
   
  但是你的情况好像不一样,因为用的是同一个connection。  
   
  在死锁发生的时候,你去查一下是不是有v$lock,看看能不能找到一点线索。  
   
  Top

19 楼superrg(秀华)回复于 2002-01-11 19:41:30 得分 0

KingSunSha(弱水三千):  
  怎么查v$lock呢?现在我在设打印断点,结果出来一大堆等待信号,也不知道哪一个是最后一个了~~~~~~~Top

20 楼superrg(秀华)回复于 2002-01-11 19:53:57 得分 0

我用OEM查,结果发现有九个会话,其中6个是后台的,一个是调试程序的,一个是sql   plus的,另外一个是OEM进入时用的,而总共有十个锁,在两个后台会话中的,其中sid为2的会话有九个锁,锁类型都是MR型,占用的模式为share,资源id1为1-8   、201,资源id2都为0;而sid为3的会话有一个锁,类型为RT,占用模式为独占,资源id1为1,资源id2为0,是什么原因呢???三千,快来救命~~~~~~Top

21 楼grit(东东)回复于 2002-01-11 20:41:00 得分 0

因为主线程和子线程都是等待一个信号量(event1),因此操作是线性的,应该不会锁,  
  除非操作数据库的线程发生异常,不释放信号量。  
  打印需要这么多线程吗?如果都是等一台打印机,那打印还是线性的。是不是记录是变动的  
  ,那可以一个线程处理记录,一个打印。  
  Top

22 楼superrg(秀华)回复于 2002-01-11 21:19:58 得分 0

to   grit(东东):  
  我所指的打印是指把信息从屏幕上显示出来,显示不是最终的目的~~~~Top

23 楼KingSunSha(弱水三千)回复于 2002-01-11 21:30:08 得分 0

查v$lock很容易,用select   *   from   v$lock;就可以  
   
  只是你的问题确实比较奇怪Top

24 楼superrg(秀华)回复于 2002-01-11 21:45:54 得分 0

to   KingSunSha(弱水三千):  
  哦???那你看我刚才列出的锁是否正常呢???   Top

25 楼superrg(秀华)回复于 2002-01-11 22:14:40 得分 0

实际上跟我刚才列的是一样的~~~~  
  SQL>   select   *   from   v$lock;  
   
  ADDR           KADDR                       SID   TYPE                 ID1                 ID2             LMODE         REQUEST  
  --------   --------   ----------   ----   ----------   ----------   ----------   ----------  
            CTIME             BLOCK  
  ----------   ----------  
  7AE531FC   7AE5320C                     2   MR                     201                     0                     4                     0  
            11685                     0  
   
  7AE531B0   7AE531C0                     2   MR                         8                     0                     4                     0  
            11685                     0  
   
  7AE53164   7AE53174                     2   MR                         7                     0                     4                     0  
            11685                     0  
   
   
  ADDR           KADDR                       SID   TYPE                 ID1                 ID2             LMODE         REQUEST  
  --------   --------   ----------   ----   ----------   ----------   ----------   ----------  
            CTIME             BLOCK  
  ----------   ----------  
  7AE53118   7AE53128                     2   MR                         6                     0                     4                     0  
            11685                     0  
   
  7AE530CC   7AE530DC                     2   MR                         5                     0                     4                     0  
            11685                     0  
   
  7AE53080   7AE53090                     2   MR                         4                     0                     4                     0  
            11685                     0  
   
   
  ADDR           KADDR                       SID   TYPE                 ID1                 ID2             LMODE         REQUEST  
  --------   --------   ----------   ----   ----------   ----------   ----------   ----------  
            CTIME             BLOCK  
  ----------   ----------  
  7AE53034   7AE53044                     2   MR                         3                     0                     4                     0  
            11685                     0  
   
  7AE52FE8   7AE52FF8                     2   MR                         2                     0                     4                     0  
            11685                     0  
   
  7AE52F9C   7AE52FAC                     2   MR                         1                     0                     4                     0  
            11685                     0  
   
   
  ADDR           KADDR                       SID   TYPE                 ID1                 ID2             LMODE         REQUEST  
  --------   --------   ----------   ----   ----------   ----------   ----------   ----------  
            CTIME             BLOCK  
  ----------   ----------  
  7AE52EB8   7AE52EC8                     3   RT                         1                     0                     6                     0  
            11688                     0  
   
   
  已选择10行。Top

26 楼superrg(秀华)回复于 2002-01-11 22:26:32 得分 0

三千,我把程序退出后里面还是有十个锁,可见我程序的运行好像跟锁的产生无关呀~~~~~怪怪怪~~~~~你能不能看看你的数据库初始化时都有些什么锁呀??Top

27 楼cmszzx()回复于 2002-01-11 22:48:56 得分 0

还没有搞掂吗?再帮你推推Top

28 楼superrg(秀华)回复于 2002-01-11 23:22:13 得分 0

终于搞掂了,谢谢大家的帮忙,散分罗~~~~~~~Top

29 楼KingSunSha(弱水三千)回复于 2002-01-11 23:31:31 得分 0

我的库打开以后有8个lock,类型是MR/RT,每个update语句产生两个locks,类型为TX/TM,在v$locked_object中看到每个被update语句产生一个locked_object,同时可以看到其他的一些信息,  
  SQL>   select   *   from   v$locked_object  
          XIDUSN         XIDSLOT           XIDSQN     OBJECT_ID   SESSION_ID  
  ----------   ----------   ----------   ----------   ----------  
  ORACLE_USERNAME                                 OS_USER_NAME                                       PROCESS  
  ------------------------------   ------------------------------   ---------  
  LOCKED_MODE  
  -----------  
                    5                   45                   50               4500                     7  
  KNUT                                                       Administrator                                     4752:4680  
                      3  
   
  还是不明白你的问题在哪里Top

30 楼KingSunSha(弱水三千)回复于 2002-01-11 23:33:19 得分 0

好像可以认为你的问题不在数据库端、、、、、、Top

31 楼KingSunSha(弱水三千)回复于 2002-01-11 23:34:58 得分 0

到底是什么问题?能分享一下经验吗?  
   
  我出300分,好不好?Top

32 楼superrg(秀华)回复于 2002-01-11 23:56:50 得分 0

to   KingSunSha(弱水三千):  
  谢谢你的分了,问题的确出在数据库端,我现在还正在调,因为新的锁出现了,你帮了我这么多次,我不好意思要你的分,回头给你解释我所谓的死锁,One   moment,   pls....Top

33 楼superrg(秀华)回复于 2002-01-12 00:08:05 得分 0

to   KingSunSha(弱水三千):  
  这一回不知道是哪里死锁了,更惨,先说说上面的问题,原记录数共有一万三千多条,其中有二十多条根据规则设定为废弃数据,昨天晚上我在update标记时忘了加条件,结果把这些记录都算进了正规数据中,结果当处理到这些记录里,程序一直处于等待状态,而oracle据我所知是不能直接设定操作超时的,所谓的死锁就是这样产生的;而我重新发现这个错误也算比较庆幸,办法是:把子线程总数减少到只允许一个子线程运行,结果每一次程序运行到第284条就停下来等待,于是我就查第285条记录,发现原来是一条早已废弃的数据,才猛然想起我犯的这个错。依三千你看,这是不是数据库的问题呢??只是不是数据库死锁的问题罢了,谢谢你,三千~~~~~~~Top

34 楼KingSunSha(弱水三千)回复于 2002-01-13 01:11:17 得分 0

是不是你的sql中对废弃的纪录有什么特殊的处理啊?废弃的纪录一般是在某个标记字段做了废弃的标记,对数据库操作本身不会有什么影响吧?  
  你把代码贴出来看看吧Top

35 楼SeaBig(海纳百川)回复于 2002-01-29 13:24:04 得分 0

关注!Top

36 楼wylyf(李寻欢)回复于 2002-01-31 13:42:57 得分 0

学习!Top

相关问题

  • Java 多线程中的死锁问题,数据竞争所致?
  • ORACLE死锁问题!!
  • 多线程取oracle中数据
  • 散分!求多线程书籍下载。
  • @@@@@高手帮帮忙好吗?socket 多线程通信,运行几十次就死锁!
  • 多线程的向Oracle中写的问题?在线等待
  • 关于多线程Oracle数据库编程的问题!急!
  • ORACLE死锁为什么杀不掉?
  • 关于使用多线程PRO*C程序访问ORACLE数据库的问题
  • 关于使用多线程PRO*C程序访问ORACLE数据库的问题

关键词

  • 线程
  • 数据库
  • 信号
  • 打印
  • 多线程
  • 连接
  • 代码
  • 死锁
  • 子线程
  • 记录

得分解答快速导航

  • 帖主:superrg
  • superjj2002
  • flowerofwind
  • flowerofwind
  • cmszzx
  • aimi0123456
  • Haiwer
  • mycode
  • mycode
  • KingSunSha

相关链接

  • CSDN Blog
  • 技术文档
  • 代码下载
  • 第二书店
  • 读书频道

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo