viernes, 19 de mayo de 2023

Oracle 23c & JSON - Relational Duality Views - Parte #2


En este segundo artículo sobre JSON Relational Duality Views vamos a analizar algunas características mas avanzadas de las mismas y vamos a analizar también las vistas del diccionario de datos que contienen información sobre esta nueva funcionalidad.


Control de Concurrencia Optimista

En el articulo anterior "Oracle 23c & JSON - Relational Duality Views - Parte #1" estuvimos actualizando documentos JSON mediante el uso de vistas duales, pero no contemplamos la posibilidad que los datos subyacentes hayan cambiado, algo que en la vida real ocurre frecuentemente.

Duality Views utiliza una nueva arquitectura de control de concurrencia optimista o sin bloqueo disponible en Oracle Database 23c que permite a los desarrolladores administrar sus datos de manera consistente en operaciones sin estado (como ser REST GET y PUT), ya que los bloqueos tienen estado y no se pueden retener en llamadas sin estado.

Este nuevo algoritmo posee las siguientes características:

  • Incorpora el concepto de etiqueta de entidad (ETAG) del protocolo HTTP a la base de datos, siendo una ETAG un hash o una firma para el contenido de una página web recuperada, pero esto aplicado a documentos.
  • Cuando se realiza un GET en Duality View, el documento JSON devuelto también contiene el ETAG del conjunto de filas utilizadas en la construcción del documento.
  • Cuando ese documento se modifica y luego se vuelve a poner en la base de datos, el ETAG proporcionado se compara con el ETAG actual de las filas. Si el ETAG difiere, el objeto debe haber sido modificado por otra sesión entre el momento en que se hizo el GET y el momento en que se envió el PUT, por lo que el PUT es rechazado. La aplicación puede volver a obtener la versión mas actualizada del documento (el cual contiene un nuevo ETAG) mediante un GET, aplicarle los cambios requeridos, y volver a intentar hacer un PUT.
  • Si el PUT tiene éxito, tenemos la garantía de que no se han producido cambios intermedios en el objeto y garantizamos la atomicidad y la coherencia a nivel de documento.

Este tipo de control de concurrencia sin bloqueo permite a los desarrolladores centrarse en su aplicación sin tener que implementar control de concurrencia dentro de la aplicación.


Control de Concurrencia Optimista en Funcionamiento

Vamos a ver como funciona el control de concurrencia en la práctica. Lo primero que vamos a hacer es consultar un documento en particular, usando los ejemplos del artículo "Oracle 23c & JSON - Relational Duality Views - Parte #1" donde comenzamos a explicar como funcionan las vistas duales.


Vamos a obtener el documento JSON asociado al comprobante #3, usando la siguiente sintaxis:

SELECT JSON_SERIALIZE(c.data PRETTY) FROM VDCOMPROBANTE c WHERE c.data.IDComprobante = 3;


Lo cual devuelve el siguiente documento:

JSON_SERIALIZE(C.DATAPRETTY) --------------------------------------------------------------------- { "_metadata" : { "etag" : "66C4365F9A178623F27913B947DF8C7C", "asof" : "00000000007844AF" }, "IDComprobante" : 3, "FechaComprobante" : "2023-05-16T00:00:00", "IDCliente" : 3, "Importe" : 14200, "Detalles" : [ { "IDDetalle" : 5, "IDProducto" : 5, "CantidadProducto" : 14, "ImporteUnitario" : 1000 } ] }

El valor resaltado en ROJO es el ETAG calculado para la versión actual del documento, el cual sirve para identificar a la misma.


A continuación, vamos a usar una sentencia UPDATE de SQL para actualizar en forma directa, en la tabla de detalles de comprobantes, el valor de la columna cantidad del registro de detalle #5, como vemos a continuación:

UPDATE tDetalleComprobante SET Cantidad = 7 WHERE ID_DetalleComprobante = 5;

1 row updated.


Volviendo al documento JSON que obtuvimos en el primer SELECT, asumamos ahora que la aplicación que lo obtuvo le hizo una modificación (por ejemplo, cambió el ID de cliente, como remarcamos en azul) y desea grabar dicho cambio, lo cual hace enviando el documento completo (incluyendo el ETAG que obtuvo al leer en documento) ejecutando la siguiente sentencia:

UPDATE vdComprobante c SET data = '{ "_metadata" : { "etag" : "66C4365F9A178623F27913B947DF8C7C", "asof" : "00000000007844AF" }, "IDComprobante" : 3, "FechaComprobante" : "2023-05-16T00:00:00", "IDCliente" : 500, "Importe" : 14200, "Detalles" : [ { "IDDetalle" : 5, "IDProducto" : 5, "CantidadProducto" : 14, "ImporteUnitario" : 1000 } ] }' WHERE c.data.IDComprobante = 3;


Al ejecutarla, obtendremos el siguiente mensaje de error:

Error report - ORA-42699: Cannot update JSON Relational Duality View 'VDCOMPROBANTE': The ETAG of document with ID 'FB03C10400' in the database did not match the ETAG passed in.


Esto se debe a que el ETAG del documento almacenado en la base de datos cambió al momento en que modificamos el detalle, lo cual podemos ver si volvemos a consultar el mismo:

SELECT JSON_SERIALIZE(c.data PRETTY) FROM VDCOMPROBANTE c WHERE c.data.IDComprobante = 3;


Obteniendo:

JSON_SERIALIZE(C.DATAPRETTY)
---------------------------------------------------------------- { "_metadata" : { "etag" : "5A94261D02F1232A3F126D7C36A961BD", "asof" : "00000000007848C6" }, "IDComprobante" : 3, "FechaComprobante" : "2023-05-16T00:00:00", "IDCliente" : 3, "Importe" : 14200, "Detalles" : [ { "IDDetalle" : 5, "IDProducto" : 5, "CantidadProducto" : 7, "ImporteUnitario" : 1000 } ] }


Con la versión "actualizada" del documento, la aplicación tiene que volver a aplicar el cambio individual deseado (actualizar el cliente) y volver a enviar todo el documento, con el ETAG que ahora si coincide con la versión almacenada en la base de datos.


Vistas del Diccionario de Datos

El diccionario de datos de Oracle 23 incorpora algunas nuevas vistas para acceder a la información de las vistas duales JSON Relacional. Veremos las mismas en detalle a continuación (analizaremos las visas que comienzan con USER_, que permiten acceder a los objetos del usuario conectado, existen versiones con prefijo ALL_ y DBA_ que ven todos los objetos sobre los que el usuario posee permisos y todos los objetos de la base de datos respectivamente).


USER_JSON_DUALITY_VIEWS

Esta vista contiene información general de cada JSON Relational Duality View definida en el esquema.

SELECT * FROM USER_JSON_DUALITY_VIEWS;


Las columnas ALLOW_INSERT, ALLOW_UPDATE y ALLOW_DELETE nos indican que tipo de acciones se pueden realizar sobre las mismas. La columna JSON_SCHEMA contiene el esquema JSON que describe al documento que esta disponible al utilizar cada una de las vistas.


USER_JSON_DUALITY_VIEW_TABS

Esta vista nos muestra la tabla principal y todas las tablas involucradas en cada una de las vistas duales:

SELECT * FROM USER_JSON_DUALITY_VIEW_TABS;


USER_JSON_DUALITY_VIEW_TAB_COLS

Esta vista muestra información sobre todas las columnas (atributos del documento JSON) definidas en una vista dual:

SELECT * FROM USER_JSON_DUALITY_VIEW_TAB_COLS;


La columna JSON_KEY_NAME nos indica el nombre de atributo en el documento JSON y las columnas PRIMARY_KEY_POSETAG_POS nos indica si forma parte de la clave primaria (y en que posición) y en que posición se encuentra dentro del ETAG.


USER_JSON_DUALITY_VIEW_LINKS

Esta vista nos permite entender las relaciones entre las distintas tablas en cada vista / documento JSON:

SELECT * FROM USER_JSON_DUALITY_VIEW_LINKS;


Conclusión

En este artículo hicimos un análisis del mecanismo de control de concurrencia optimista (sin lockeos) implementado en JSON Relational Duality Views y las vistas del diccionario de datos que contienen información


Si desean conocer más sobre Oracle 23c, es recomendable que vean estos artículos en este blog como punto de partida:

Adicionalmente, pueden consultar todos los artículos relacionados a Oracle Database 23c agrupados en en el tag Database 23c.

No hay comentarios.:

Publicar un comentario