You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET连接Oracle 11g突发对象状态无效错误求助

问题:夜间批处理任务突然抛出"Operation is not valid due to the current state of the object"异常

我有一个每日夜间运行的批处理任务,此前一直执行成功,但今日突然抛出异常:Operation is not valid due to the current state of the object。未修改任何代码(该代码由他人编写),无法确定异常源于环境、代码还是数据。

经定位,异常发生在代码行:Dim rotate As Short = DirectCast(dr("ROTATE"), Short)

异常堆栈跟踪

Oracle.DataAccess.Client.OracleDataReader.GetOrdinal(String name)
Oracle.DataAccess.Client.OracleDataReader.get_Item(String columnName)
MyProject.Package.Filing.Core.Yakan.LinkDataCreate.ImageCreateWorker.Execute(Object obj)

相关代码

Public Sub Execute(ByVal obj As Object)

    Dim errorCount As Integer = 0

    ' 2018/06/18
    LogManager.GetLogger.PutLog(LogLevel.Information, "ImageCreateWorker::Execute(),开始")

    Do
        If errorCount >= Me._retryCount Then
            Dim message As String = String.Format("Worker处理发生错误。基准年:{0}、IJP:{1}", Me._kijunNen, Me._ijp)
            Dim newEx As FilingException = New FilingException(message, String.Empty)
            LogManager.GetLogger.PutLog(LogLevel.Error, newEx, String.Empty)
            Throw newEx
        End If

        '依次获取图像。
        Using agent As New ImageCommandAgent
            agent.Kijun_nen = Me._kijunNen
            agent.HonpyoIJP = Me._ijp
            agent.IsRyomen = Me._isRyomen

            Using codec As New Codecs.RasterCodecs()

                ' 磁盘内存使用标志
                codec.Options.Load.DiskMemory = Me._diskMemoryFlg

                Dim image As RasterImage = Nothing

                ' 2018/06/19
                LogManager.GetLogger.PutLog(LogLevel.Information, "ImageCreateWorker::Execute() ExecuteReader,开始")

                Using dr As System.Data.Common.DbDataReader = agent.ExecuteReader(Me._dbConnection)

                    ' 2018/06/19
                    LogManager.GetLogger.PutLog(LogLevel.Information, String.Format("ImageCreateWorker::Execute() ExecuteReader,结束,IJP:{0}", agent.HonpyoIJP))

                    Try
                        While dr.Read()

                            ' 2018/06/19
                            LogManager.GetLogger.PutLog(LogLevel.Information, "ImageCreateWorker::Execute() IMAGE_DATA MemoryStream,开始")

                            Using ms As New IO.MemoryStream(DirectCast(dr("IMAGE_DATA"), Byte())), _
                                  singleImage As RasterImage = codec.Load(ms)

                                ' 2018/06/19
                                LogManager.GetLogger.PutLog(LogLevel.Information, String.Format("ImageCreateWorker::Execute() IMAGE_DATA MemoryStream,结束,IJP:{0}", agent.HonpyoIJP))
                                '此处抛出异常
                                Dim rotate As Short = DirectCast(dr("ROTATE"), Short)
                                If rotate <> 0 Then

                                    ' 2018/06/19
                                    LogManager.GetLogger.PutLog(LogLevel.Information, "ImageCreateWorker::Execute() Rotate,开始")

                                    Dim Rcommand As RotateCommand = New RotateCommand()
                                    Rcommand.Angle = rotate * 9000
                                    Rcommand.Run(singleImage)

                                    ' 2018/06/19
                                    LogManager.GetLogger.PutLog(LogLevel.Information, String.Format("ImageCreateWorker::Execute() Rotate,结束,IJP:{0}", agent.HonpyoIJP))

                                End If

                                '转换为灰度后添加到主体。

                                ' 2018/06/19
                                LogManager.GetLogger.PutLog(LogLevel.Information, "ImageCreateWorker::Execute() Grayscale,开始")

                                Dim command As New GrayscaleCommand()
                                command.BitsPerPixel = 8
                                command.Run(singleImage)

                                ' 2018/06/19
                                LogManager.GetLogger.PutLog(LogLevel.Information, String.Format("ImageCreateWorker::Execute() Grayscale,结束,IJP:{0}", agent.HonpyoIJP))

                                If image Is Nothing Then
                                    image = singleImage.CloneAll    '第一张
                                Else
                                    ' 2018/06/19
                                    LogManager.GetLogger.PutLog(LogLevel.Information, "ImageCreateWorker::Execute() AddPage,开始")

                                    image.AddPage(singleImage) '追加

                                    ' 2018/06/19
                                    LogManager.GetLogger.PutLog(LogLevel.Information, String.Format("ImageCreateWorker::Execute() AddPage,结束,IJP:{0}", agent.HonpyoIJP))

                                End If

                            End Using
                        End While

                    Catch ex As System.Exception
                        ' 异常结束
                        If Not image Is Nothing Then
                            image.Dispose()
                            image = Nothing
                        End If

                        Dim message As String = String.Format("【警告】表单图像获取失败。基准年:{0}、IJP:{1}", Me._kijunNen, Me._ijp)
                        Dim newEx As FilingException = New FilingException(message, ex, String.Empty)
                        LogManager.GetLogger.PutLog(LogLevel.Warning, newEx, String.Empty)
                        LogManager.GetLogger.PutLog(LogLevel.Warning, ex.Message)
                        LogManager.GetLogger.PutLog(LogLevel.Warning, ex.StackTrace)

                        errorCount = errorCount + 1
                        Continue Do

                    End Try
                End Using ' ■■ datareader ■■

                Try
                    ' 2018/06/19
                    LogManager.GetLogger.PutLog(LogLevel.Information, "ImageCreateWorker::Execute() 文件夹检索,开始")

                    If Not System.IO.Directory.Exists(PathName) Then
                        CreateDirectory(PathName)
                    End If

                    ' 2018/06/19
                    LogManager.GetLogger.PutLog(LogLevel.Information, String.Format("ImageCreateWorker::Execute() 文件夹检索,结束,IJP:{0}", agent.HonpyoIJP))

                    ' 2018/06/19
                    LogManager.GetLogger.PutLog(LogLevel.Information, "ImageCreateWorker::Execute() 文件检索,开始")

                    If IO.File.Exists(FileFullPath) Then
                        ' 由于save方法无法覆盖,先删除文件
                        IO.File.Delete(FileFullPath)
                    End If

                    ' 2018/06/19
                    LogManager.GetLogger.PutLog(LogLevel.Information, String.Format("ImageCreateWorker::Execute() 文件检索,结束,IJP:{0}", agent.HonpyoIJP))

                    ' 2018/06/19
                    LogManager.GetLogger.PutLog(LogLevel.Information, "ImageCreateWorker::Execute() 图像保存,开始")

                    Select Case ImageMode
                        Case "BINARY"
                            '■■以二进制多页TIF保存时■■
                            codec.Save(image, FileFullPath, RasterImageFormat.CcittGroup4, 1)

                        Case "BINARY-DITH"
                            '' ■■指定抖动以二进制保存时■■
                            image.DitheringMethod = RasterDitheringMethod.FloydStein
                            codec.Options.Save.UseImageDitheringMethod = True
                            codec.Save(image, FileFullPath, RasterImageFormat.CcittGroup4, 1)

                        Case "GRAY"
                            '' ■■以灰度多页TIF保存时■■
                            codec.Options.Jpeg.Save.QualityFactor = 255
                            codec.Save(image, FileFullPath, RasterImageFormat.TifJpeg, 8)

                        Case Else
                            '' 其他情况,推荐以灰度保存。
                            codec.Options.Jpeg.Save.QualityFactor = 255
                            codec.Save(image, FileFullPath, RasterImageFormat.TifJpeg, 8)

                    End Select

                    ' 2018/06/19
                    LogManager.GetLogger.PutLog(LogLevel.Information, String.Format("ImageCreateWorker::Execute() 图像保存,结束,IJP:{0}", agent.HonpyoIJP))

                Catch ex As System.Exception
                    ' 异常结束
                    If Not image Is Nothing Then
                        image.Dispose()
                        image = Nothing
                    End If

                    Dim message As String = String.Format("【警告】图像文件输出失败。基准年:{0}、IJP:{1}", Me._kijunNen, Me._ijp)
                    Dim newEx As FilingException = New FilingException(message, ex, String.Empty)
                    LogManager.GetLogger.PutLog(LogLevel.Warning, newEx, String.Empty)
                    LogManager.GetLogger.PutLog(LogLevel.Warning, ex.Message)
                    LogManager.GetLogger.PutLog(LogLevel.Warning, ex.StackTrace)

                    errorCount = errorCount + 1
                    Continue Do
                Finally
                    If Not image Is Nothing Then
                        image.Dispose()
                        image = Nothing
                    End If
                End Try

                ' 2018/06/18
                LogManager.GetLogger.PutLog(LogLevel.Information, String.Format("ImageCreateWorker::Execute(),结束,IJP:{0}", Me._ijp))

                Exit Do

            End Using ' codec
        End Using ' agent
    Loop

    ' 线程结束通知
    ' 2019/11/03 加入try-catch捕获异常
    'OnFinishedEventHandler(EventArgs.Empty)
    Try
        LogManager.GetLogger.PutLog(LogLevel.Information, "ImageCreateWorker::线程结束通知")
        OnFinishedEventHandler(EventArgs.Empty)

    Catch ex As System.Exception
        Dim message As String = "线程结束通知失败"
        Dim newEx As FilingException = New FilingException(message, ex, String.Empty)
        LogManager.GetLogger.PutLog(LogLevel.Warning, newEx, String.Empty)

    End Try

End Sub

分析与解决方案

异常根源定位

从堆栈跟踪和出错代码来看,异常触发点是OracleDataReader的GetOrdinal方法,说明读取ROTATE列时存在以下问题:

  1. 数据层面:当前处理的数据库记录中,ROTATE列不存在、列名大小写与代码中的"ROTATE"不匹配(Oracle默认区分大小写),或者列值为DBNull
  2. DataReader状态异常:读取IMAGE_DATA后执行codec.Load(ms)耗时过长,导致数据库连接超时、DataReader提前关闭,状态失效
  3. SQL语句问题:ImageCommandAgent执行的SQL未包含ROTATE列,或列名拼写错误

排查与修复步骤

  1. 检查异常数据:

    • 根据日志中的IJP值,查询对应数据库记录,确认ROTATE列是否存在、列名大小写是否匹配,以及列值是否为DBNull
    • 若存在异常数据,临时修复或过滤该记录后重新执行任务
  2. 验证数据库环境:

    • 确认数据库连接正常,无临时中断、权限变更情况
    • 检查ImageCommandAgent中的SQL语句,确保包含ROTATE列且拼写正确
  3. 代码优化:

    • 提前读取所有列值:避免长时间操作导致DataReader状态失效,先把需要的列值读取到本地变量再处理:
      While dr.Read()
          ' 提前读取所有需要的列值
          Dim imageData As Byte() = DirectCast(dr("IMAGE_DATA"), Byte())
          Dim rotate As Short = If(dr.IsDBNull(dr.GetOrdinal("ROTATE")), 0, DirectCast(dr("ROTATE"), Short))
          
          Using ms As New IO.MemoryStream(imageData), _
                singleImage As RasterImage = codec.Load(ms)
              ' 后续处理逻辑不变
              If rotate <> 0 Then
                  ' 旋转操作
              End If
              ' ...其他代码
          End Using
      End While
      
    • 增加列存在性检查:避免因列名错误引发异常:
      Dim rotateOrdinal As Integer
      Try
          rotateOrdinal = dr.GetOrdinal("ROTATE")
      Catch ex As IndexOutOfRangeException
          ' 列不存在时设默认值0
          rotateOrdinal = -1
      End If
      Dim rotate As Short = If(rotateOrdinal = -1 Or dr.IsDBNull(rotateOrdinal), 0, DirectCast(dr(rotateOrdinal), Short))
      
    • 增强日志:记录当前处理记录的主键等标识,方便快速定位异常数据

内容的提问来源于stack exchange,提问作者Pathfinder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 07:35:16