数据库Access violation 问题,实在是搞不明白,快被它搞疯了。代码简单,但问题有难度 ( 积分: 200 )

D

Dlwxn

Unregistered / Unconfirmed
GUEST, unregistred user!
程序是服务的形式,在2000下没有任何问题,在2003双核的情况下才会出现。<br>出现的概率不大,每天大概一到两次,出现后服务就挂了。<br>为了调试,我写在每个语句上面都对ErrorCode进行了改变。<br>ErrorCode&nbsp;=&nbsp;的值有时候是1、6、11,也就是说随机的。<br><br>Access&nbsp;violation&nbsp;at&nbsp;address&nbsp;006C6974.&nbsp;Write&nbsp;of&nbsp;address&nbsp;0112E530<br><br>下面的代码:代码逻辑比较简单,稍微看一下就能明白。<br><br>变量定义:<br>nmg_ADOConnection&nbsp;:TADOConnection<br><br>//是写日志的过程,可以不用管。<br>AddLogToFileEx<br>//NMC_SQLText_UpdateLineInfo&nbsp;是常量,SQL语句。<br><br>{-------------------------------------------------------------------------------<br>&nbsp;&nbsp;功能:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;保存用户状态到数据库&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;过程名:&nbsp;&nbsp;&nbsp;&nbsp;TNEGMMangerState.SaveStateToDataBase<br>&nbsp;&nbsp;作者:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Steven<br>&nbsp;&nbsp;日期:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2007.06.04<br>&nbsp;&nbsp;参数:<br>&nbsp;&nbsp;AID:&nbsp;Integer;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//用户ID<br>&nbsp;&nbsp;AState:&nbsp;Integer;&nbsp;&nbsp;&nbsp;&nbsp;//状态标准<br>&nbsp;&nbsp;AStateText:&nbsp;string;&nbsp;//状态名称<br>&nbsp;&nbsp;ALoginOut:&nbsp;Boolean&nbsp;&nbsp;//是否登出<br>&nbsp;&nbsp;返回值:&nbsp;&nbsp;&nbsp;&nbsp;无<br>-------------------------------------------------------------------------------}<br>procedure&nbsp;TNEGMMangerState.SaveStateToDataBase(AID:&nbsp;Integer;<br>&nbsp;&nbsp;AState:&nbsp;Integer;&nbsp;AStateText:&nbsp;string;&nbsp;ALoginOut:&nbsp;Boolean);<br>var<br>&nbsp;&nbsp;nmm_ADOQu:&nbsp;TADOQuery;<br>&nbsp;&nbsp;I,&nbsp;ErrorCode:&nbsp;string;<br>begin<br>&nbsp;&nbsp;I&nbsp;:=&nbsp;'0';<br>&nbsp;&nbsp;ErrorCode&nbsp;:=&nbsp;'0';<br>&nbsp;&nbsp;try<br>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;Self.nmg_ADOConnection&nbsp;=&nbsp;nil&nbsp;then&nbsp;Exit;<br>&nbsp;&nbsp;&nbsp;&nbsp;ErrorCode&nbsp;:=&nbsp;'1';<br>&nbsp;&nbsp;&nbsp;&nbsp;nmm_ADOQu&nbsp;:=&nbsp;CreateAdoQueryEx(Self.nmg_ADOConnection);<br>&nbsp;&nbsp;&nbsp;&nbsp;ErrorCode&nbsp;:=&nbsp;'2';<br>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;nmm_ADOQu&nbsp;=&nbsp;nil&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ErrorCode&nbsp;:=&nbsp;'3';<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Exit;<br>&nbsp;&nbsp;&nbsp;&nbsp;end;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;nmm_ADOQu&nbsp;do<br>&nbsp;&nbsp;&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ErrorCode&nbsp;:=&nbsp;'4';<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;ALoginOut&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ErrorCode&nbsp;:=&nbsp;'5';<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SQL.Add(NMC_SQLText_UpdateLineInfo);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ErrorCode&nbsp;:=&nbsp;'6';<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SQL.Add(NMC_SQLText_UpdateUserLine);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ErrorCode&nbsp;:=&nbsp;'7';<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SQL.Add(NMC_SQLText_UpdateLineWhere);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ErrorCode&nbsp;:=&nbsp;'8';<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Parameters.ParamByName('ID').Value&nbsp;:=&nbsp;AID;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ErrorCode&nbsp;:=&nbsp;'9';<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Parameters.ParamByName('E_Name').Value&nbsp;:=&nbsp;'';<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ErrorCode&nbsp;:=&nbsp;'10';<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Parameters.ParamByName('Negm_UserStatus').Value&nbsp;:=&nbsp;AStateText;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ErrorCode&nbsp;:=&nbsp;'11';<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Parameters.ParamByName('Negm_IsonLine').Value&nbsp;:=&nbsp;AState;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ErrorCode&nbsp;:=&nbsp;'12';<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;ALoginOut&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ErrorCode&nbsp;:=&nbsp;'13';<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Parameters.ParamByName('DataObject').Value&nbsp;:=&nbsp;0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ErrorCode&nbsp;:=&nbsp;'14';<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ExecSQLCommand(Self.nmg_MutexHandle,&nbsp;nmm_ADOQu,&nbsp;ecs_Exec);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ErrorCode&nbsp;:=&nbsp;'15';<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;on&nbsp;E:Exception&nbsp;do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;nmm_ADOQu&nbsp;=&nbsp;nil&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddLogToFileEx('nmm_Adoqu&nbsp;is&nbsp;null&nbsp;11');<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddLogToFileEx(E.Message,&nbsp;'NEGM_Svr_State-&gt;uMain.pas',&nbsp;'SaveStateToDataBase&nbsp;&nbsp;&nbsp;11');<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;finally<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;not&nbsp;(nmm_ADOQu&nbsp;is&nbsp;TADOQuery)&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddLogToFileEx('nmm_ADOQu&nbsp;is&nbsp;not&nbsp;valid');<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;not&nbsp;(Self&nbsp;is&nbsp;&nbsp;TNEGMMangerState)&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddLogToFileEx('Self&nbsp;is&nbsp;not&nbsp;valid');<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;not&nbsp;(nmg_ADOConnection&nbsp;is&nbsp;TADOConnection)&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddLogToFileEx('nmg_ADOConnection&nbsp;is&nbsp;not&nbsp;valid');<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I&nbsp;:=&nbsp;'free';<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FreeAndNil(nmm_ADOQu);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CoUninitialize;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;<br>&nbsp;&nbsp;&nbsp;&nbsp;end;<br>&nbsp;&nbsp;except<br>&nbsp;&nbsp;&nbsp;&nbsp;on&nbsp;E:&nbsp;Exception&nbsp;do<br>&nbsp;&nbsp;&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddLogToFileEx('dword(@Self)&nbsp;:'&nbsp;+&nbsp;&nbsp;IntToStr(dword(@Self)));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddLogToFileEx('(PDWORD(Self.nmg_ADOConnection))^&nbsp;&nbsp;:'&nbsp;+&nbsp;IntToStr((PDWORD(Self.nmg_ADOConnection))^&nbsp;));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddLogToFileEx('dword(@Self.nmg_ADOConnection)&nbsp;:'&nbsp;+&nbsp;&nbsp;IntToStr(dword(@Self.nmg_ADOConnection)));<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddLogToFileEx('i&nbsp;=&nbsp;'&nbsp;+&nbsp;i);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddLogToFileEx('ErrorCode&nbsp;=&nbsp;'&nbsp;+&nbsp;ErrorCode);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddLogToFileEx('nmm_intTemp&nbsp;=&nbsp;'&nbsp;+&nbsp;IntToStr(nmm_intTemp));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(I&nbsp;&lt;&gt;&nbsp;'free')&nbsp;and&nbsp;(nmm_ADOQu&nbsp;=&nbsp;nil)&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddLogToFileEx('nmm_Adoqu&nbsp;is&nbsp;null');<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddLogToFileEx(E.Message,&nbsp;'NEGM_Svr_State-&gt;uMain.pas',&nbsp;'SaveStateToDataBase');<br>&nbsp;&nbsp;&nbsp;&nbsp;end;<br>&nbsp;&nbsp;end;<br>end;<br><br><br>function&nbsp;CreateAdoQueryEx(AADOConn:&nbsp;TADOConnection):&nbsp;TADOQuery;<br>begin<br>&nbsp;&nbsp;Result&nbsp;:=&nbsp;nil;<br>&nbsp;&nbsp;if&nbsp;AADOConn&nbsp;=&nbsp;nil&nbsp;then<br>&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;Exit;<br>&nbsp;&nbsp;end;<br>&nbsp;&nbsp;CoInitialize(nil);<br>&nbsp;&nbsp;Result&nbsp;:=&nbsp;TADOQuery.Create(nil);<br>&nbsp;&nbsp;try<br>&nbsp;&nbsp;&nbsp;&nbsp;Result.Connection&nbsp;:=&nbsp;AADOConn;<br>&nbsp;&nbsp;&nbsp;&nbsp;Result.Close;<br>&nbsp;&nbsp;&nbsp;&nbsp;Result.SQL.Clear;<br>&nbsp;&nbsp;&nbsp;&nbsp;Result.Parameters.Clear;<br>&nbsp;&nbsp;except<br>&nbsp;&nbsp;&nbsp;&nbsp;on&nbsp;E:&nbsp;Exception&nbsp;do<br>&nbsp;&nbsp;&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddLogToFileEx(E.Message,&nbsp;'uFunction.pas',&nbsp;'CreateAdoQueryEx');<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FreeAndNil(Result);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CoUninitialize;<br>&nbsp;&nbsp;&nbsp;&nbsp;end;<br>&nbsp;&nbsp;end;<br>end;<br><br><br><br><br>从属模块:&nbsp;D:/netmarch/NTService/Plugins/NEGM_Svr_State.dll<br>09:01:33&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;=&nbsp;free<br><br>从属模块:&nbsp;D:/netmarch/NTService/Plugins/NEGM_Svr_State.dll<br>09:01:33&nbsp;&nbsp;&nbsp;&nbsp;ErrorCode&nbsp;=&nbsp;7<br><br>从属模块:&nbsp;D:/netmarch/NTService/Plugins/NEGM_Svr_State.dll<br>09:01:33&nbsp;&nbsp;&nbsp;&nbsp;nmm_intTemp&nbsp;=&nbsp;1000<br><br>从属模块:&nbsp;D:/netmarch/NTService/Plugins/NEGM_Svr_State.dll<br>09:01:33&nbsp;&nbsp;&nbsp;&nbsp;单元名:&nbsp;NEGM_Svr_State-&gt;uMain.pas<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;过程名:&nbsp;SaveStateToDataBase<br>////////////////////////////////////////////////<br><br>ErrorCode&nbsp;=&nbsp;的值有时候是1、6、11,也就是说随机的。<br>nmm_intTemp&nbsp;是Self的一个全局变量,在Self.Create的时候赋值为1000,为了判断出错的时候,Self对象是表示不存在了。
 
你可以改用adoquery.connectionstring='数据库连接'<br>不要用adquery.connection&nbsp;=adoconn.<br>试试.可能有用..
 
可能是由频繁连断数据库造成的,如果用了线程也有可能有冲突
 
to:newsmile<br><br>&nbsp;ErrorCode&nbsp;:=&nbsp;'1';&nbsp;在这个时候,出现了异常。而CreateAdoQueryEx没有写异常的日志。<br>这个时候并没有做数据库的连接。<br>程序中用到了多线程,但是执行查询的时候,我做了线程同步保护。
 
建议查线程,可能线程同步保护没做好,以前串行双核时并行了
 
Access&nbsp;violation&nbsp;at&nbsp;address&nbsp;006C6974.&nbsp;Write&nbsp;of&nbsp;address&nbsp;0112E530<br><br>这两个地址分别处在哪里?&nbsp;<br><br>线程同步,&nbsp;只要操作共享变量/对象的,&nbsp;恐怕都很可能需要保护.&nbsp;估计应该是线程问题.不过如&nbsp;杂志上所说的,真实的物理多处理器,和单处理器的多线程,还是有差异的。单核多线程能够正常工作(至少看起来如此),不一定在多处理器就OK。
 
to:zjan521<br>这两个地址,因为是随机出现,一天到晚的在这个地方设置断点F7或F8,很难受了。<br><br>只能怀疑是线程同步没有做好。只有在执行SQL的时候,用互斥做了线程同步,其他地方就没有用到。nmg_ADOConnection&nbsp;是全局的数据库连接。<br><br>按照道理,用try&nbsp;excetp异常保护,出现问题,服务也不应该直接挂的。肯定问题不是太简单。偏偏这个地方一直出现问题,而程序中很多执行SQL,其它的地方就没有。
 
不要使用全局的数据库连接,应该没次执行SQL是新建一个ADOConnection对象,执行SQL完成后,关闭ADOConnection
 
CoUninitialize;这个是不是成对出现啊》?<br>CreateAdoQueryEx中把except改成finally
 
我觉得可能是你使用全局的ADOConnection出错的,我如果在线程里面使用ADO,会在线程中CoInitializeEx和CoUninitialize包含所有ADO组件的创建,然后在线程中使用,就是说每个线程就是一个数据库连接,这样使用基本上不会范什么错误。
 
再罗嗦一句,ADO是COM组件,这种组件对线程及其敏感,在主线程和自由线程访问一个COM资源时,需要进行很复杂的背景切换(或者叫线程访问切换),建议不要在主线程创建任何自由线程使用的COM组件。可以参考一下COM组件方面的书。
 
顶部