Professional Documents
Culture Documents
Un par de meses atrs escrib sobre buffer; pero deliberadamente dej fuera de la discusin dos funciones vitales mientras
trabajaba con buffer- nombradas TableUpdate() y TableRevert(). Estas son la base mediante la cual usted, el desarrollador,
controla la transferencia de los datos entre el buffer de Visual FoxPro y el origen de datos originales. La funcin
TableUpdate() toma los datos pendientes desde el buffer y los actualiza en la tabla original, mientras TableRevert() refresca
los buffers para releer el dato desde el origen de datos. La realizacin exitosa de otras funciones da como resultado un buffer
'limpio' lo que significa que, para Visual FoxPro, los buffer y el origen de datos son sincronizados.
Ambas funciones TableUpdate() y TableRevert() operan sobre una tabla al mismo tiempo. El comportamiento
predeterminado es que, a menos que especficamente, se determine lo contrario; actuar en la tabla en el rea de trabajo
seleccionada. Si no hay una tabla abierta en el rea de trabajo, hay un error (No se encuentra el alias - Error 13). Ambos, sin
embargo, pueden actuar sobre una tabla abierta disponible en la sesin de datos actual y puede aceptar cualquiera de los
nombres de ALIAS (el tercer parmetro para TableUpdate(), segundo para TableRevert()) o un nmero de rea de trabajo.
No recomendamos el uso del nmero del rea de trabajo en esto, o cualquiera, situacin donde est especificando una tabla
diferente que la seleccionada. Tal y como hemos podido ver esta funcionalidad est incluida, slo por compatibilidad hacia
atrs y no tiene lugar en el entorno VFP. Existen dos razones para evitar el uso del rea de trabajo. Primeramente, hace su
cdigo dependiente de tablas especficas estn abiertas en reas especficas de trabajo - lo que es aun mayor limitacin si
piensa cambiar! En segundo lugar, no tiene control real sobre las tablas abiertas en VFP, los cursores o vistas cuando utiliza
de cualquier forma el Entorno de datos del formulario. Entonces, liberar el nmero del rea de trabajo en lugar del alias, es
una estrategia muy arriesgada e innecesaria.
El nico momento que recomendamos el uso del nmero de rea de trabajo es cuando guardamos el rea de trabajo actual
guardando el valor devuelto de la funcin SELECT(0). Utilizar el nmero del rea de trabajo en este caso asegura que el rea
de trabajo actual est vaca, o que las tablas que contienen se cierren durante cualquier operacin que est haciendo, puede
aun devolverlo sin error.
Conclusin
Existe mucha funcionalidad y flexibilidad oculta dentro de TableUpdate() y TableRevert(). Al utilizar buffer, necesita tener
cuidado de, exactamente cules de varias combinaciones de sus parmetros, puede pasarles para asegurar que est
utilizando la combinacin correcta que necesita. Mientras TableRevert() es bastante simple, TableUpdate() es ms compleja y
por eso, en la Tabla 2 que muestro debajo se brinda un resumen de algunas combinaciones "prcticas" de parmetros para
TableUpdate().
Tabla 2. Opciones de TableUpdate()
Parmetros
Alcanc
e
Fuerz
a
Tabl
a
Salid
a
Accin
0 .F.
.F.
0 .F.
.T.
0 .F.
.F./.T.
1 .T.
.F.
1 .T.
.T.
1 .T.
.F./.T.
Alias
.F.
Alias
.T.
.F./.T.
Alias
Intenta actualizar la fila actual slo del alias especificado. Se detiene en un fallo
Matriz
Intenta actualizar todos los registros disponibles del alias especificado. Nota los fallos;
pero no se detiene.
Fuerza la actualizacin de todos los registros disponibles del alias actual/especificado
Alias
Matriz
En la prctica, existen muchas situaciones donde puede ocurrir legtimamente. Considere la situacin en una Orden de
Ventas en el procesamiento del sistema. Cuando se coloca una orden para un elemento, el "stock disponible" actual debe
reajustarse para reflejar la reduccin. Si dos usuarios, que son controlados por dos operadores simultneamente, incluyen el
mismo elemento en sus rdenes, existe un gran posibilidad de que surja un conflicto. Obviamente, esto puede no ocurrir si el
sistema utiliza bloqueo pesimista; pero esto tiene otras consecuencias, generalmente indeseables. En este caso, el segundo
operador, que trata de acceder al elemento en cuestin, recibir un mensaje que el registro est en uso por alguien y no
puede hacer modificaciones - no es mucha ayuda ! An ms, el bloqueo pesimista puede ser utilizado cuando una tabla
Visual FoxPro es utilizada directamente como origen de dato - no puede bloquear de forma pesimista una vista de cualquier
tipo (ni para datos locales o remotos).
Al utilizar buffer, Visual FoxPro hace una copia de todos los datos como e recuperan de la tabla fsica, cuando se pide una
actualizacin, se compara esa copia con el estado actual del dato. Si no hay cambios, la actualizacin es permitida, en otro
caso, la actualizacin se genera un error de conflicto (#1585 para las vistas, #1595 para tablas).
He aqu cuatro estrategias bsicas para actualizar conflictos. Puede escoger una, o combine ms de una en una aplicacin en
dependencia de la situacin real:
[1] El usuario actual siempre gana - Esta estrategia es apropiada solamente en aquellas situaciones en las que se asume
que son correctos los datos del usuario que est actualmente intentando guardar. Tpicamente esto debera ser
implementado en la base del ID del usuario, el que es en realidad est haciendo el guardado y debera implementar una
regla de negocio que cierta informacin de una gente es ms til que otra.
Un ejemplo podra ser tener una aplicacin donde un operador hable al usuario podra tener derechos de sobreescritura para
contactar informacin para el cliente (en la base que la persona realmente habla al cliente es ms probablemente capaz de
obtener los detalles correctos). El conflicto puede surgir en este caso cuando un administrador est actualizando un detalle
de cliente desde un dato en archivo o ltima orden, mientras un operador tiene detalles nuevos, directamente desde el
cliente. La implementacin de esta estrategia en Visual FoxPro es muy sencilla. Simplemente establezca el parmetro
"FORCE", (el segundo) en la funcin TableUpdate() a ".T." y reintente la actualizacin.
[2] El usuario actual siempre pierde - Esto es exactamente lo contrario a la anterior. Al usuario actual se le permite
solamente guardar los cambios siempre que no hay otro usuario que haya hecho cambios. Por el contrario, ser
implementado normalmente en base al ID del usuario y podra reflejar la probabilidad que este usuario en particular es
propenso a trabajar con informacin "histrica" en lugar de informacin "actual". La implementacin en Visual FoxPro es
tambin muy sencilla. Los cambios del usuario actual se revierten, se recarga la informacin original y el usuario tiene que
hacer cualquier cambio que necesite, una vez ms. Esta es, probablemente la estrategia que es adoptada ms
frecuentemente - pero usualmente en base global.
[3] El usuario actual gana a veces - Esta estrategia es la ms compleja de las cuatro a implementar; pero es en la
actualidad, bastante frecuente. El principio bsico es que cuando ocurre un conflicto de actualizacin, usted determina si
alguno de los campos, que el usuario actual ha cambiado, van a afectar los cambios hechos por otro usuario. Si no, el
registro del usuario actual es actualizado automticamente (utilizando el valor de CURVAL()), entonces esto provoca que es
negado el conflicto y la actualizacin se reintenta. Sin embargo, debido a no puede cambiar los valores devueltos por
OldVal(), necesita forzar la segunda actualizacin.
Incidentalmente, esta estrategia tambin est dirigida al problema de cmo controlar el conflicto de actualizacin "falso
positivo". Esto ocurre cuando existen discrepancias entre los valores del disco y aquellos en el buffer de usuario, pero los
actuales cambios del usuario, no crean en realidad un conflicto con cualquier otro cambio que se haya hecho. Claramente,
esta situacin no es en realidad un conflicto; pero necesita ser controlada.
Aunque no es trivial, la implementacin en Visual FoxPro es relativamente fcil. Primero, la funcin CURVAL() es utilizada
para determinar cmo actualizar el buffer de usuario actual de tal forma que no va sobreescribir los cambios hechos por otro
usuario. Entonces, la actualizacin se aplica utilizando el segundo parmetro FORCE en el TableUpdate() para decirle a Visual
FoxPro que ignore el conflicto que van a surgir porque OldVal() y CurVal() no corresponden.
[4] El usuario actual decide - Este es el caso de "Coge todo". El conflicto no falla bajo ninguna regla de negocio
reconocida, as que la nica solucin es preguntarle al usuario cuya accin de guardar desencadena el conflicto que es lo que
desea hacer. La idea bsica es que usted muestre al usuario que ha desencadenado el conflicto con una lista de valores aquellos que acaba de entrar) y el valor que hay ahora en la tabla ( es decir con el cual alguien ha cambiado el valor
original). El usuario puede entonces decidir si hay que forzar o revertir sus propios cambios. Las herramientas bsicas para la
implementacin de esta estrategia han sido discutidos en secciones anteriores. Todo lo requerido es determinar qu cambios
traen conflicto y los presentan al usuario como va para que el usuario pueda decidir en un campo a campo qu hacer, en
base al conflicto. En la prctica, esta estrategia en general se combina con la estrategia [3] mostrada antes, as al usuario
slo se le presenta una lista de campos donde hay un conflicto en los campos que han modificado por ellos mismos.
En el prximo artculo de esta serie, ver el diseo e implementacin de una clase que controle un conflicto que puede ser
arrastrada a un formulario.