VC++执行Update SQL语句挂死问题分析

最近本人在项目中遇到了一个莫名其妙的问题,数据存储服务软件运行一段时间后,总会出现执行Update语句挂死的现象,在网上查找了资料,还是没有找到原因,经过一段痛苦的分析历程,终于发现问题所在,现把经验与大家分享,希望对大家有所帮助。

1、软件背景

本人用VC++开发了一个数据库存储软件,负责集中处理各业务软件的数据存储,数据库为Oracle11g。为了提高数据存储效率,在软件中根据业务数据类型,SQL语句分配到不同的线程中执行。

2、问题描述

该数据库存储软件在超过100项目中使用,有的项目不间断运行时间超过1年均无出现存储异常的问题,但最近有几个项目反馈该数据存储软件丢失数据,即没有把数据保存到数据库中。

经过对软件日志文件的分析,发现软件运行一段时间后(短的几个小时,长的几天),其中的一个线程执行更新表T_Data的SQL语句时挂死,表现为执行Update时已进入到调用Winddows ADO API ,但调用后一直处于执行中状态,函数没有返回;此时,其它线程运行正常,执行插入、删除、查找、更新操作均成功。

3、问题分析

(1)通过上述分析,排除Oracle数据库和Windows API调用错误的因素;

(2)该软件在绝大多数项目中使用均无异常,其它项目也需执行表T_Data的Update操作,区别只在于更新的字段和更新条件不同,因此也可初步排除由软件本身的bug而引起的因素;

(3)通过多次的跟踪分析发现,在同一项目中,部分更新表T_Data的SQL语句可正常执行,只有少部分更新语句出现挂死的现象,因此,可初步定位于表T_Data的部分行被锁住了。

当软件出现线程挂死时,在PLSQL中执行下述语句,该语句可找出给数据库表加锁的执行程序信息:

select sid,username,osuser,machine,program,event from v$session t where t.SID in (select sid from v$lock t where t.BLOCK=1 or t.REQUEST<>0)

果然,发现另外一台服务器S上的PLSQL在执行下面的SQL语句:

select * from T_Data  t   where t.条件='条件A'  for update

该SQL语句执行后没有提交或执行回滚操作,导致表T_Data的某些行被锁住,当数据库存储软件对这些行执行更新操作时,则会处于等待状态,从而造成线程挂死的假象。

关闭服务器S上的PLSQL,数据库存储软件所有线程恢复正常,等待执行的SQL语句迅速执行完毕,问题解决。

吐舌头大笑


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值