La línea Microsiga Protheus adopta el nivel de aislamiento READ UNCOMMITTED. Este nivel de aislamiento permite lecturas sucias, donde la transacción corriente o las otras pueden visualizar los datos de las transacciones pendientes.
El nivel de aislamiento adoptado garantiza que las lecturas realizadas en la base de datos mediante la aplicación no realicen el bloqueo de registros y consecuentemente no serialicen la aplicación, manteniendo la previsibilidad del desempeño. Sin embargo, se debe tomar cuidado para garantizar la integridad de los datos.
Cuando se adoptan lecturas sucias debe prevenirse que en la actualizaciones, los datos se bloqueen antes de actualizarse o leerse para este fin. La transacción T2 tiene una línea modificada, pero aún no se finalizó. La transacción T1 lee los datos actualizados y los actualiza con base en los datos leídos. La transacción T1 finaliza la transacción y la transacción T2 realiza un Roll Back de los datos. A partir de este momento los datos ya no están íntegros.
Para evitar esta situación, el desarrollador debe indicar la aplicación en el momento del bloqueo, esto se realiza utilizando la función RecLock, de acuerdo con lo siguiente:
// ReadSample.prw
Begin Transaction
RecLock("SB2")
nQtd := SB2->B2_QATU
If nQtd + nSoma <= 0
SB2->B2_QATU := 0
Else
SB2->B2_QATU := nQtd - nSoma
EndIf
MsUnlock()
End Transaction
La función RecLock informa al Framework de la aplicación para realizar el bloqueo del registro marcado. El Framework realiza el bloqueo y actualiza la lectura del registro corriente de la tabla. Las otras transacciones del sistema continúan leyendo el registro bloqueado, pero si intentan bloquear el registro tienen que esperar a que la transacción anterior lo libere, lo que solamente podrá realizarse al final de la transacción.
Otra prevención que debe considerarse en las lecturas sucias son las actualizaciones parciales, resultantes del vínculo de dependencia directa de las tablas. Para un formulario del tipo Master/Detail (encabezado e ítem), la transacción de inclusión de este formulario permite que el registro de la tabla Master exista sin los registros o con una cantidad parcial de los registros de la tabla Detail, ya que es la única forma de garantizar la dependencia de la clave extranjera. Si una rutina de actualización realiza el bloqueo únicamente en los registros Detail no hay cómo garantizar que se consideren todos los registros.
Por lo tanto, es necesario bloquear el registro Master, antes del inicio del bloqueo de los registros Detail en cualquier actualización de los registros Detail. Al bloquear el registro Master, se garantiza que ningún registro de la tabla Detail, vinculado al Master, esté en actualización o inclusión. Es un hecho que dependiendo de la rutina desarrollada, es obligatorio iniciar la lectura por la tabla Detail y no por la Master. En estas situaciones debe garantizarse que, antes de cualquier actualización del registro Detail, se bloquee el registro Master antes del registro Detail.
En el ejemplo se mencionan únicamente dos tablas, pero independientemente de la cantidad de tablas involucradas en el formulario, debe bloquearse el registro Master.
Por último, existe la prevención del momento del COMMIT. La arquitectura del Server Application de la línea Microsiga Protheus hace posible que el momento del COMMIT sea automático, de acuerdo con la lógica del programa, además de poder utilizar más de un canal de comunicación con el SGBD para lectura. Si el Server Application utiliza más de un canal para lectura, es posible deducir que los otros canales de lectura solamente "visualizarán" los registros, cuyos datos pasaron por el COMMIT. Para prevenir cualquier tipo de problema en la lectura por medio de querys, es necesario forzar el COMMIT de los datos, como se muestra a continuación.
// CommitSample.prw
SPED050->(DbCommit())
BeginSQL Alias cAlias
SELECT R_E_C_N_O_
FROM SPED050
WHERE ID_ENT = %Exp:cIdEnt% AND
(STATUS = 1 OR STATUS = 2 OR STATUSDPEC = 1) AND
STATUSDPEC <> 5 AND
%NOTDEL%
EndSQL
El nivel de aislamiento READ UNCOMMITTED es el más aconsejable para la aplicación del tipo de aplicación OLTP (On Line Transaction Process), pero corresponde al desarrollador el control del formato de lectura y el bloqueo del registro para actualización.