Professional Documents
Culture Documents
Dnde comenzamos?
Parece que trabajar con datos en buffer en Visual FoxPro causa mucha confusin. Creo que es en gran medida debido a la
confusin en la implementacin del buffer y en parte tambin, por problemas de nomenclatura (por estndares
convencionales) asociados al tema.
Por ejemplo, para definir buffer para un archivo DBF de Visual FoxPro, que es una tabla, tenemos que utilizar la funcin
CURSORSETPROP(), que est excesivamente sobrecargada. Por qu no tener una funcin separada, sin ambigedades, "
SetBufferMode()"? Para confirmar una transaccin pendiente el comando es END TRANSACTION. Por qu no "COMMIT"
como en el resto de los lenguajes de bases de datos - una opcin que incluso es ms peculiar ya que el estndar
"ROLLBACK" se utiliza para revertir una transaccin?
Adems, quizs debido a que Visual FoxPro implementa el bloqueo de los registros (lo contrario a "Pgina"), el hecho de
controlar la colocacin y liberacin de los bloqueos est inseparablemente enlazada con el buffer. Por ejemplo, para permitir
buffer de filas, (que solamente opera sobre un slo registro) SET MULTILOCKS debe estar en "ON". De acuerdo con el archivo
Ayuda, esta configuracin solamente determina la capacidad de Visual FoxPro para bloquear mltiples registros en la misma
tabla - y que de todas formas, est limitado a la actual sesin de datos. Esto no parece ser muy lgico y no es realmente
sorprendente que la gente est totalmente confusa.
Qu significa "buffer"?
El principio es realmente muy simple. Cuando hace cambios en algn dato, esos cambios no es escriben en la tabla fuente,
en lugar van a un rea de almacenaje (el "Buffer") hasta el momento en que le indica a Visual FoxPro que deben ser
guardados en el almacn permanente o eliminarlos. Esta rea de almacenaje es lo que, en la actualidad, ve en Visual FoxPro
cuando se utiliza una tabla de buffer, en realidad un cursor actualizable basado en la tabla original. Todos los cambios se han
hecho sobre este cursor y slo se escriben en la tabla cuando se utiliza el comando "update" adecuado.
Estrategias de buffer
La estrategia de buffer determina cundo y cmo se almacenan en la tabla los cambios que se encuentran en el buffer.
Existen tres opciones:
No se emplea buffer: Esta va es solamente una opcin para las versiones anteriores a Visual Foxpro versin 3.0 y
es adems, el comportamiento predeterminado actualmente para las tablas de Visual FoxPro. Cualquier cambio
hecho en una tabla va directamente e inmediatamente a la tabla original. No hay posibilidad de "deshacer" sin que
se haya programado explcitamente - utilizando Scatter y Gather, por ejemplo. Se establece al asignar "1" como
parmetro a CursorSetProp()
Buffer de filas: Los cambios no se han enviado a la tabla original a menos que ocurran una de estas dos cosas. O
hay una llamada explcita a la funcin TableUpdate(), o el puntero del registro se mueve dentro de la tabla original.
Vea que CUALQUIER movimiento del puntero del registro, aunque sea iniciado por una tabla que est en buffer de
filas, siempre causa un TableUpdate() "implcito". Establezca 2 3 como parmetro para CursorSetProp().
Buffer de tabla: Los cambios nunca se envan automticamente a la tabla original, a menos que exista una llamada
a un comando TableUpdate() o TableRevert() siempre debe afectar los cambios que estn guardados en el buffer.
Intentar cerrar una tabla con buffer mientras tiene cambios no cometidos provoca que Visual FoxPro genere un error
en la versin 3.0; pero este comportamiento cambi en versiones anteriores por tanto, los cambios pendientes
simplemente se pierden. (No hay error; ni advertencia de que los cambios se van a perder). Se establece asignando
4 5 como parmetro para CursorSetProp().
Hasta este punto se est preguntando, por qu hay DOS parmetros posibles para cada una de las estrategias que
implementan buffer. La respuesta es, como se indica en la introduccin, debido a que hay dos estrategias de bloqueo.
Estrategias de bloqueo
Visual FoxPro necesita bloquear el registro fsico en la tabla mientras se realizan los cambios en su contenido y existen dos
vas con las que se puede establecer el bloqueo automtico (opuesto al uso explcito de las funciones RLock()/FLock())
Bloqueo pesimista: El registro se bloquea en cuanto un usuario comienza a hacer cambios (El bloqueo en realidad
ocurre en cuanto se oprime cualquier tecla vlida). Esto evita que cualquier otro usuario pueda hacer o guardar
cambios sobre este registro hasta tanto el usuario actual haya completado sus cambios y liberado el registro tanto
guardando o revirtiendo los cambios.
Bloqueo optimista: Un intento de bloqueo del registro se hace solamente cuando los cambios se comienzan a
enviar a la tabla. Esto significa que incluso mientras un usuario hace cambios en el dato, el registro permanece
disponible a otros usuarios, los que tambin podran, y posiblemente guardarn, cambios en el mismo registro
mientras el primer usuario estn aun trabajando en el.
Modos de buffer
El modo de buffer para una tabla es, por tanto, la combinacin especfica de las estrategias de Buffer y Bloqueo que se
aplican. Existe un total de 5 modos de buffer para una tabla como se ilustra en la Tabla 1.
Tabla 1. Modos de Buffer en Visual FoxPro
Mod
o
Bloqueo
Buffer
Pesimista
Ningun
o
Pesimista Fila
El bloqueo se establece por el evento KeyPress. El movimiento del puntero de registro obliga a
Guardar
Optimist
a
Pesimista Tabla
Optimist
a
Fila
Tabla
Comentarios
nica opcin para FP2.x, predeterminado para tablas VFP
Al trabajar con Visual FoxPro, debemos ser cuidadosos al distinguir entre estrategias individuales, que se especifican
directamente para Buffer y Bloqueo, y el modo buffer que resulta de la combinacin de ellos. Desafortunadamente, como
hemos visto, Visual FoxPro es de por s, menos cuidadoso con esta distincin.
0 Ninguno (predeterminado)
1 Pesimista
2 Optimista
Vea que esto se refiere en realidad a las opciones para la estrategia de bloqueo y no tiene nada que ver con el buffer para
nada !! El hecho por el cual el formulario determina la estrategia buffer es por sus tablas todas por si mismo, basadas en su
utilizacin. Si un formulario utiliza dos tablas que tienen una relacin de uno a muchos, muestran el lado "muchos" de la
relacin de diferentes formas.
Si la tabla "muchos" se utiliza como origen de datos para el control grid, para el formulario, se abre con buffer de tabla. Sin
embargo, si la tabla "muchos" se emplea para enlazar con controles que solamente muestran una fila de la tabla cada vez
entonces, el buffer para la tabla va a ser lo mismo que para "una" tabla para toda de configuracin de la propiedad
Buffermode del formulario.
Si crea un pequeo formulario de prueba y ejecuta todas sus opciones para la propiedad Buffermode de un formulario, puede
ver que incluso con la propiedad BufferMode establecida en 0-(Ninguna) el cursor creado por Visual FoxPro est aun abierto
en modo buffer de fila cuando las tablas se abren desde el entorno de datos del formulario. Es como si para el formulario "No
buffer" y "Bufer de filas" fuera lo mismo.
Sin embargo, este NO es el caso si las tablas se abren directamente con el comando USE. Si las tablas se abren
explcitamente en el mtodo Load(), entonces la propiedad Buffermode no tiene impacto en lo absoluto, y las tablas se abren
en dependencia de los parmetros apropiados en la Sesin de datos. Para formularios que corren en la sesin
predeterminada de datos (DataSession = 1) se utilizan los parmetros especificados en la ventana Opciones. Vea que en la
ventana Opciones, las opciones, en realidad establecen la configuracin del modo de bufer. Tiene las 5 opciones que se
corresponden con lo 5 modos definidos antes, en la Tabla 1, y los que utilizan los mismos identificadores que la funcin
CursorSetProp(). Si el formulario se ejecuta en sesin privada de datos, entonces, las tablas abiertas con el comando USE se
configuran en dependencia de la configuracin establecida para esa sesin de datos y, de forma predeterminada, no sern
alojadas en buffer.
Aun confundido?
Lo ms que puedo decir es que la situacin es realmente como sigue:
Para las tablas abiertas por el entorno de datos del formulario, no importa si el formulario tiene Datassesion con
valor Default o Private. Las tablas siempre tienen almacenamiento en buffer, al menos en modo Optimista de filas.
La propiedad BufferMode del formulario en realidad determina la estrategia de bloqueo, no el modo de buffer; pero
solo para tablas que han sido abiertas en el entorno de datos del formulario.
En la sesin de datos actual, las tablas que han sido abiertas explcitamente tienen ambas estrategias: buffer y
bloqueo establecidas en dependencia de la ventana Opciones.
En la sesin Privada de datos, las tablas que han sido abiertas explcitamente tienen sus estrategias de buffer y
bloqueo establecidas de acuerdo a los parmetros que se han aplicado para esta sesin (Predeterminado = "No
Buffering")
Estos resultados se pueden verificar estableciendo varias opciones en un formulario sencillo y mostrando el resultado
que se obtiene por CURSORGETPROP("BUFFERING")
Utilizar BufferModeOverride
La clase dataenvironment posee una propiedad para cada tabla (o, mejor dicho, "cursor") llamado "BufferModeOverride".
Esta propiedad va a fijar el modo del buffer para esa tabla (y slo esa tabla) a una de las estas seis opciones - si, es
correcto, SEIS opciones, no cinco - veamos:
0 Ninguno
Existen dos puntos sobre los que hay que prestar atencin. Primero, Vea que mientras los nmeros del 2 al 5 se
corresponden con los parmetros de CursorSetProp() y son aquellos mismos que estn disponibles desde el dilogo
Opciones, el valor requerido para la configuracin "ninguno" ahora es 0 en lugar de 1. He aqu otra inconsistencia en la
configuracin del buffer. Segundo, vea que el valor predeterminado para esta propiedad es "1 - Utiliza la configuracin de
formularios". Cuando se refiere a configuracin de formularios, se refiere, por supuesto a la propiedad "BufferMode", la que
como ya hemos visto en realidad se encarga de definir la estrategia de bloqueo a aplicar. No existe configuracin del
formulario para controlar buffer !!.
Habiendo dicho esto, la configuracin de la propiedad BufferModeOverride va a asegurar que la tabla se abre utilizando el
modo buffer que usted ha especificado. Al menos esta propiedad ha sido nombrada correctamente, sobreescribe todo lo
dems y fuerza la tabla a un modo especial de buffer en todas las situaciones.
Utilizar CursorSetProp()
Independientemente de cmo fue abierta la tabla, siempre puede utilizar la funcin CursorSetProp() para cambiar el modo
buffer de una tabla. Sin embargo, si est utilizando el entorno de datos del formulario para abrir sus tablas, entonces, tiene
dos opciones en dependencia de si su formulario utiliza sesin privada de datos o sesin actual de datos. En el primer caso,
puede establecer simplemente el modo requerido en la ventana Opciones y olvidarse de ello. Todas las tablas se van a abrir
siempre con esa configuracin y siempre sabr en qu estado se encuentra. Si utiliza una sesin privada de datos entonces,
necesita hacer dos cosas. Primero, necesita asegurarse de que el entorno de datos est configurado para soportar buffer.
Algunos parmetros de entorno se limitan a la sesin de datos actual y puede que necesite cambiar el comportamiento
predeterminado o alguno, o todos los siguientes (vea el tema SET DATASESSION en el archivo ayuda para una lista completa
de parmetros afectados):
Lo segundo que necesita es especificar explcitamente el modo buffer de cada tabla utilizada en la funcin CursorSetProp()
con el parmetro apropiado porque la configuracin en la ventana Opciones no se puede aplicar a la sesin privada de datos.
Aun ms importante, el hecho de que configure una tabla para buffer de tabla no lo previene de que la tabla como si en
realidad hubiera buffer de filas. Ambas funciones TableUpdate() y TableRevert(). Esto puede significar que tiene que escribir
un poco ms de cdigo; pero puede evitar muchos problemas.