Windows服务多次重试连接Oracle时ExecuteNonQuery报内存保护错误求助
我之前维护一个类似的Windows服务时,遇到过完全相同的问题!当时折腾了好几天才找到几个可行的排查方向,分享给你参考:
检查Oracle驱动与环境的兼容性
这个是我当时解决问题的关键!之前用的是非托管ODP.NET驱动,不仅和系统32/64位架构不匹配,版本和Oracle服务器版本也差距较大,很容易出现内存相关的异常。建议换成Oracle.ManagedDataAccess.Client(托管驱动),它不需要在服务器上安装Oracle客户端,兼容性更好,内存管理也更稳定。确保数据库资源被正确释放
重试逻辑里如果每次都创建新的OracleConnection或OracleCommand但没有释放,多次重试后会导致资源泄漏、内存碎片,进而触发保护内存的错误。一定要用using块包裹资源,确保即使报错也能自动释放:using (var conn = new OracleConnection(yourConnectionString)) { conn.Open(); using (var cmd = new OracleCommand(yourSql, conn)) { cmd.ExecuteNonQuery(); } }优化重试逻辑的资源占用
不要设置无限重试的逻辑,给重试次数加个合理上限(比如最多5次),避免积累过多的线程或连接资源。另外,如果是异步场景,用Task.Delay替代Thread.Sleep,减少线程池资源消耗;同步场景下也要确保每次重试前清理掉上一次的所有资源。排查Oracle服务器端的状态
可以让DBA帮忙检查Oracle服务器的连接数、会话状态,看看是否存在连接耗尽、异常会话占用资源的情况。也可以调整连接字符串参数,比如暂时关闭连接池(Pooling=false)测试是否是连接池导致的问题,或者合理设置Max Pool Size参数。检查Windows服务的运行权限
服务运行的账号如果权限不足,或者内存配额被系统限制,也可能触发这类内存访问错误。可以尝试将服务的运行账号切换为本地管理员账号,测试是否能缓解问题。
当时我是更换了托管ODP.NET驱动,同时修复了资源泄漏的问题,之后就再也没出现这个错误了。你可以逐个排查试试!
内容的提问来源于stack exchange,提问作者user6398876

