Artículo
· 26 abr, 2024 Lectura de 4 min

Comprobación de Versión en objetos. "ERROR:5800"

Si tenéis tablas de sistema que implementan la funcionalidad "VERSIONPROPERTY", podéis encontraros con el error 5800. Este artículo explica cómo se produce este error y proporciona soluciones para resolver el problema.

Cuando se implementa la comprobación de versiones, la propiedad especificada por VERSIONPROPERTY se incrementa automáticamente cada vez que se actualiza una instancia de la clase (ya sea mediante objetos o SQL).

Por ejemplo:

ClassMethod RunVersionChange() As %Status
{
    Set sample = ##class(dado.TblSample).%OpenId("42")
    Write !,"VERSIONPROPERTY value: "_ sample.VersionCheck

    Do sample.StatusSetObjectId("AL")
    DO sample.%Save()
    WRITE !,!,"SAVED",!

    Write !,"VERSIONPROPERTY value: "_ sample.VersionCheck
}

Después de ejecutar el comando %Save(), la propiedad VersionCheck del objeto se incrementó en 1.

Esta característica es útil para realizar evaluaciones y auditorías de registros de bases de datos.

En CACHÉ/IRIS, un mismo objeto que extienda una clase %Persistent puede tener su OREF compartida dentro del mismo proceso.

Por ejemplo:

ClassMethod RunVersionChangeSameProcess() As %Status
{
    Set firstInstance = ##class(dado.TblSample).%OpenId("42")
    Set secondInstance = ##class(dado.TblSample).%OpenId("42")

    Write !,"VERSIONPROPERTY first instance value: "_ firstInstance.VersionCheck
    Write !,"VERSIONPROPERTY second instance value: "_ secondInstance.VersionCheck

    Do firstInstance.StatusSetObjectId("QR")
    Do firstInstance.%Save()
    WRITE !,!,"EXECUTED SAVE on first instance ",!

    Write !,"VERSIONPROPERTY first instance value: "_ firstInstance.VersionCheck
    Write !,"VERSIONPROPERTY second instance value: "_ secondInstance.VersionCheck
}

Esto implica que, mientras estén en el mismo proceso, el VersionCheck definido en VERSIONPROPERTY de la tabla dado.TblSample siempre estará actualizado en todas sus instancias.

Sin embargo, cuando se realiza un cambio en diferentes procesos, no ocurre lo mismo, como se demuestra en el ejemplo:

ClassMethod RunVersionChangeTwoProcess() As %Status
{
    Set sample = ##class(dado.TblSample).%OpenId("42")

    Try {
        Do sample.StatusSetObjectId("AL")
        $$$THROWONERROR(sc,sample.%Save())

        Write !,"VERSIONPROPERTY BEFORE EXECUTING JOB: "_ sample.VersionCheck

        JOB ##class(s01.Error5800).RunVersionChange()
        hang 2

        Do sample.StatusSetObjectId("EP")
        Write !,"VERSIONPROPERTY AFTER EXECUTING JOB: "_ sample.VersionCheck

        Write !,"TRY RUN SAVE: "
        $$$THROWONERROR(sc,sample.%Save())

    }
    Catch ex {
        WRITE !,!,"In the CATCH block"
        WRITE !,"Error code=",ex.Code

        Do sample.%Reload()
        Write !,!,"VERSIONPROPERTY AFTER Reload: "_ sample.VersionCheck
    }
}

En este ejemplo, la línea JOB JOB ##class(s01.Error5800).RunVersionChange() se ejecuta después de una instancia de tblSample, sin embargo el proceso 2 realizó un cambio en el mismo registro ya instanciado en JOB 1, finalizándolo antes de tblSample.%Save() en el primer proceso, causando la desincronización de VersionCheck entre procesos.

Esto provoca el ERROR 5800:

Al consultar el registro en la base de datos, encontramos que el VersionCheck está en una versión más antigua en comparación con el proceso 1:

Para evitar el problema, después de las llamadas asíncronas que pueden cambiar el mismo registro de la base de datos, se recomienda utilizar %Reload antes de realizar los cambios necesarios, como en el ejemplo:


ClassMethod RunVersionChangeTwoProcessWithReload() As %Status { Set sample = ##class(dado.TblSample).%OpenId("42") Try { Do sample.StatusSetObjectId("AL") $$$THROWONERROR(sc,sample.%Save()) Write !,"VERSIONPROPERTY BEFORE EXECUTING JOB: "_ sample.VersionCheck JOB ##class(s01.Error5800).RunVersionChange() hang 2 Do sample.%Reload() Do sample.StatusSetObjectId("EP") Write !,"VERSIONPROPERTY AFTER EXECUTING JOB: "_ sample.VersionCheck Write !,"TRY RUN SAVE: " $$$THROWONERROR(sc,sample.%Save()) } Catch ex { WRITE !,!,"In the CATCH block" WRITE !,"Error code=",ex.Code Do sample.%Reload() Write !,!,"VERSIONPROPERTY AFTER Reload: "_ sample.VersionCheck } }

Comentarios (0)1
Inicie sesión o regístrese para continuar