Resumen ADO ... Cursores, Bloqueos. Como elegirlos?   (2 mensajes )

Mensaje enviado por "Oswaldo D'Acevedo" <Oswaldo@heuristika.com>



PRIMERA PARTE

Cuando de ADO se trata un lugar comun para muchos de nosotros es decidir, al momento de analizar estrategias de acceso a la data, que proveedor usar?, en que lugar correra el cursor; del lado del server? (Server side cursor?) o del lado del cliente (Client side cursor), que tipo de Cursor (Forward-Only, Static, Keyset o Dinamic?)... y por si fuera poco, aun nos falta decidir que tipo de Bloqueo usar (Locking ) (read only, pessimistic, optimistic o batchoptimistic?).

Todos los autores coinciden en que la decision no es simple y es mucho mas un problema de analisis del sistema que una aplicacion matematica.

Vamos por partes:

Que es un "CURSOR" para ADO?

Un CURSOR en terminos de bases de datos representa la manera de tratar un numero discreto de registros en forma de filas de data. El cursor le permite a uno moverse a traves del set de registros y posicionarse en uno de ellos para acceder a su data.

Al momento de elegir el cursor tenemos que decidir el lugar donde este correra (Cursor location), el comportamiento del mismo en terminos de moverse a traves del recorset (tipo de cursor) y su habilidad para permitir al usuario alterar la data original y la manera de hacerlo para evitar conflictos (Bloqueo o "Locking").

Cursor Location. (Lugar donde correra el Cursor)

Para determinar el lado donde correra el cursor del recorset se debera implementar la propiedad CursorLocation del objeto recorset. Si no se especifica el rocorset tendra por "default" el valor que tenga la propiedad CursorLocation del objeto Connection que usara el recorset. El valor "default" (por defecto) de la propiedad CursorLocation del objeto Connetion es adUseServer (cursor del lado del server), que no siempre es el optimo.

Hay cuatro posibilidades de eleccion, pero nos enfocaremos en dos de ellos, ya que los otros dos son obsoletos, y a decir de MS se ha mantenido para efectos de compatibilidad con anteriores versiones

1 - adUseNone (obsoleto)
2 - adUseServer (default)
3 - adUseClient
3 - adUseClientBatch (obsoleto, pero no entiendo por que tiene el mismo numerico que anterior...no importa :-))

Entonces nos enfocaremos en los dos del medio.

Client-Side Cursors (3 - adUseClient, Cursores del lado del cliente)

Usa los recursos (memoria, cpu, etc.) de la maquina local (la del cliente), para implementar el cursor y su set de records.

Ventajas
- Dado que corre en la maquina del cliente la performance sera mejor si se trata de recorset de tamaño razonable (depende de la configuracion, basicamente de la memoria de la maquina para definir "razonable").
- Tambien la escalabilidad del sistema se ve favorecida dado que la performance depende de cada maquina cliente y no del server, en consecuencia los cursores del lado del cliente exige menos demanda del server cuando el numero de clientes crece que cuando se usa el cursor del lado del Server (Server-side Cursor).
- Es el unico cursor que permite usar recorsets desconectados (de especial uso en N Tier systems).

Desventajas:
- Para recorset muy extensos (otra vez , extensos para una maquina cliente dependera de sus recursos), la estacion de trabajo podria tener problemas para manejar grandes volumenes de data.
- Dado que el cursor del lado del cliente tiene que traer la data a traves del network, recorsets grandes significaran un alto consumo del trafico del network. Esto es especialmente un problema cuando se usa la internet.
- No todos los "proveedores" manejan bien los Campos Autonumericos o Identity field (el proveedor de Jet si lo hace muy bien)

Server-side Cursors (2 - adUseServer (default), cursores del lado del server).

Usa los recursos del server para implementar el cursor y su set de records.

Ventajas
- Las maquinas del cliente o estaciones de trabajo no se veran en peligro con grades porciones de recorsets ya que el cursor es manejado totalemente el el server. (thin client)
- Dado que no toda la data es transferida al cliente el trafico del network no se ve sobrecargado.
- Para recorsets que se preven muy grandes es mejor manejarlos de esta manera

Desventajas
- Para recorsets pequeños es ineficiente ya que todo pedido de movimento tiene que se hecho a traves del network, en tal caso es mejor transferir todo el recorset al cliente (usando cliente-side cursor).
- Se presentan problemas de escalabilidad, miemntras mas usuarios se incremente an el sistema mas carga significara para el server, pudiendo de esta manera rapidamente consumirse los recursos del server.
- Problemas de concurrencia a la data, exige un mejor manejo de las conecciones. (se hace necesario el manejo del "pool" de conecciones y el uso de programas como el MTS).


SEGUNDA PARTE

En esta segunda parte escribire sobre los cuatro tipos de Cursores que ADO maneja, sus comportamientos y algunas otras consideraciones que pienso pertinentes tener en cuenta.

Tipo de Cursor (Curso type), en terminos de ADO, indica el comportamiento que tiene dicho Cursor, lo que se puede o no hacer con el y hasta se puede saber cuan liviano o pesado es en terminos de los recursos del sistema.

Se puede definir el tipo de Cursor a usar en un recorset, especificando la propiedad CursorType antes de abrir dicho recorset (no se puede cambiar el tipo de Cursor luego de que el recordset haya sido adquirido). El siguiente seria un ejemplo:

MiRecord.CursorType = adOpenOptimistic
MiRecord.Open

Existe, como ya dijimos en la primera parte, cuatro tipo de cursores en ADO:
Forward-Only, Static, Keyset y Dynamic.

Forward-Only. (adOpenForwardOnly)
Este tipo de cursor se comporta mas como un archivo secuencial y solo puede manipularse en la maquina del cliente de uno en uno y en estricto orden secuencial desde el primer record hasta el ultimo.

Vale decir que no se puede saltar records ni regresar a uno anterior, la unica manera de moverse es de uno en uno y partiendo del primer record hasta el ultimo.

Para enfatizar lo anterior debe pensarse que el unico metodo,respecto a movimiento entre registro,que se puede usar es MoveNext, cualquier otro intento generara un error (runtime error).

Cursor tipo Forward-Only es el cursor por default por que es el mas economico en terminos de recursos, sin embargo no esta disponible para Cursores en el lado del Cliente (Client Cursors).

MyRecord.CursorType = adOpenForwardOnly

Nota: Traten de usar este tipo de cursor si lo que necesitan solamente es mostrar datos (en grids o en reportes). una vez "poblados" sus variable u objetos entonces cierren el recorset para "liberar" recursos (incluso si pueden cerrar la coneccion, haganlo).

Static (adOpenStatic)
Es menos "economico" que Forward-Only pero tiene una gran flexibilidad en terminos de movimiento a traves del recorset. Podemos movernos por el recorset en todas las direcciones de uno en uno o saltar records, hacer filtros, busquedas, "bookmarks".

Static es el unico cursor soportado por Cursores en el lado del Cliente (Client side Cursors),.

Una desventaja muy grande para este tipo de cursores se presenta en el hecho de que cualquier cambio hecho por otro usuario (o programa corriendo al mismo momento) no se ve reflejado en el recorset.

Esto es especialmente importante en ambientes multiusuarios donde, asumiendo que, por ejemplo, un usuario X abre un recorset con cursor "static" del lado del cliente, no le sera posible ver los cambios hechos por un usuario Y desde otra maquina, ya sean modificaciones adiciones o borrados (deletes) de dichos records. Entonces al momento de hacer Update el usuario X podria tener colisiones o conflictos que debera manejarlos mediande codigo (atrapando errores)

Nota: dos propiedades de el objeto Field de ADO ayudan a manejar este tipo de conflictos (Field.OriginalValue y Field.UnderlyingValue), el primero represanta el valor del campo cuando se solicito el record (sin considerar cualquier cambio que el usuario haga) mientras el segundo (y mas importante a lo hora de verificar cambios) representa el valor del campo en la misma base de datos incluyendo cualquier cambio que otro usuario haya hecho en el interin.

Hay ademas un par de maneras mas solucionar estos confictos uno de ellos es capturar los errores en el momento de hacer UpdateBatch. si un error ha ocurrido entonces podran hacer un filtro del recorset usando adFilterConflictingRecords que ver cuales de los registros han prentado problemas.

Keyset (adOpenKeyset)
Este tipo de cursores tienen la misma flexibilidad de "Static cursor" para el movimiento. Adicionalmente cualquier cambio hecho por otros usuarios a los records seran inmediatamente visibles por recorset activo; pero no se veran adiciones o borrados (deletes) hechos por otros usuarios.

Es obvio saber que un cursor de este tipo es mucho mas "costoso" en terminos de recursos de sistema, si a esto agregamos el hecho que este tipo de cursor solo puede ser usado en Cursores del lado del Server (Server side cursor) entonces tendremos un problema en terminos de "escalabilidad" ya que pocos usuarios podrian causar "atoros" en el server.

Dynamic (adOpenDynamic)
Caramba, por favor traten de evitarlo... :-), en verdad es muy "pesado".
Tiene toda la flexibilidad del cursor tipo Keyset, con la ventaja de que se pueden "ver" ademas los borrados (deletes) o adiciones hechos por otros usuarios en el recorset.

Traten de evitarlo pues en terminos de "escalabilidad" es una calamidad.

TERCERA PARTE (ultima)

En esta tercera y ultima entrega escribire sobre las diferentes estrategias de bloqueo (locking strategies) que reconoce ADO para poder garantizar la integridad de la data.

Tambien, al finalizar, hare un resumen sobre algunos criterios que se pueden tener al momento de elegir un Cursor para el recorset (su lado, su tipo y su estrategia de bloqueo, "CursorLocation", "CursorType" y "LockType").

Estrategias de bloqueo (Locking Strategies)

En lo que refiere a ADO existen cuatro tipos de estrategias de bloqueo: Read-Only (solo para lectura), Pessimistic, Optimistic y Batch-Optimistic. (la propiedad LockType del objeto recorset debe ser establecida antes de abrir el recorset)

Ejemplo:

MiRocord.LockType = adLockReadOnly
MiRecord.Open

Las estrategias de bloqueo nos ayudan a garantizar la integridad de la data en el momento de actualizar la misma despues de manipularla mientras esta a nuestra disposicion a traves de un recorset. Sobre todo nos permitira elegir la estrategia que consideremos adecuada para evitar conflictos de data si es que dos o mas usuarios tratan de acceder y manipular la misma data al mismo tiempo.
Pintando esto un poco mas imaginemos que el vendedor A esta haciendo la venta de 3 unidades del producto X que en inventario se le presentan 5 unidades; por otro lado el vendedor B tambien esta haciendo una venta del producto X y necesita 4 unidades; aqui claramente hay un problema de "timing", si ambos leen que hay 5 unidades en algun momento habra un conflicto de cantidades si ambos llegan a finalizar la venta. Las diferentes estrategias de bloqueo nos permitiran manejar este tipo de circunstancias de
una manera relativamente simple.

Read-Only (adLockreadOnly)
Cuando un cursor es abierto con esta opcion entonces el usuario no podra alterar ni adicionar ni borrar ninguno de los registros del recorset. Esto obviamente garantiza que no habra conflictos con cualquier manipulacion que otro usuario pueda hacer a la data en ese momento.
Este tipo de bloqueo es muy util cuando uno esta seguro que no se alterara la data (solo para consulta). Una combinacion de este tipo de bloqueo con un cursor tipo Forward-Only producira el cursor mas "economico" disponible en terminos de recursos (solo puede Cursor ser en el lado del Server). Usado ampliamente para consultas de data.

Pessimistic (adLockPessimistic)
Este tipo de bloqueo garantiza que ningun otro usuario podra manipular la data presente en nuestra recorset mientras este se ecuentra abierto. Este tipo de estrategia, si bien nos evita manipular conflictos puede ser un poco peligroso si un cliente deja abierto del recorset por mucho rato de tal manera que nadie mas pueda accesar a esa data y manipularla. (solo disponible el cursores del lado del server)

Optimistic (adLockOptimistic)
No hay ninguna garantia que el record en edicion no presentara conflictos al momento de hacer update (hay que usar las estrategias de captura de conflictos indicados en la segunda parte). El record solamente sera bloqueado mientras este en proceso de Update.

Batch Optimistic (adLockBatchOptimistic)
Para updates hechos con el metodo updateBatch del objeto recorset. Todos los cambios hechos al recordset se capturan en un cache desde el momento que se abre el recorset con esta estrategia de bloqueo; al momento de hacer UpdateBatch hay que analizar la coleccion de errores del objeto coneccion (Connection object) para capturar los conflictos que hayan ocurrido en el momento del Update.


ESCOGIENDO UNA OPCION DE CURSOR.

Como hemos visto a traves de estas tres entregas la eleccion de un cursor adecuado dependera basicamente de un buen analisis de las aplicaciones que tendra el sistema que se esta desarrolando.

Sera Monousuario?.. si es asi, se ampliara a sistemas multiusurio?, de ser multiusuario, habran muchos usuarios accesando a la misma data a la vez?, sera n sistema 2 Tier (dos capas?) o sera uno de N-tier (N capas).
Tambien podriamos no usar ningun tipo de Cursor en particular (que tal si usamos un sistema Client/server, donde todo la manipulacion de la data se hace en el server o en un server que se dedique a eso "Data server").

En cualquier caso, lo que debemos tener en cuenta a la hora de elegir un cursor es Construir un cursor que use la menor cantidad de recursos posibles de todo el sistema y que aun sea util, que aun haga el trabajo bien.

Recuerden siempre que el mas economico de todos es el que combina Forward-Only con bloqueo Read-Only y corre del lado del servidor. Traten en lo posible de usar este tipo de cusores a partir de ahi y si necesitan mas recursos traten de usar otras alternativas que sean siempre economicas y hagan bien su trabajo.

Adicionalmente, yo recomendaria usar en lo posible Store Procedures (SP) y encargar al server todo el trabajo de actualizacion de data, incluyendo el manejo de posibles conflictos.


Hasta aca termino el presente articulo que espero sirva a algunos de nosotros como partida para entender un poco mas los diferentes "sabores" de ADO.

Oswaldo D'Acevedo
Oswaldo@Heuristika.com

Mensaje enviado por "Oswaldo D'Acevedo" <Oswaldo@heuristika.com>

 Amigos:
              Hace unos dias Albin (el habitante de este universo :-)) me envio un e-mail con una serie de consultas y/o dudas que le habian surgido a partir del aporte que envie hace unas semanas sobre ADO y sus Cursores.
Este aporte esta integramente publicado en la Pagina de Jose Rubi http://www.ctv.es/USERS/jrubi que es una magnifica pagina donde se recopila muchos de los aportes hechos aca por nosotros y algunas otras fuentes (incluido,claro esta, mucho del esfuerzo propio de Jose quien merece gran reconocimiento por su labor).

 Las dudas planteadas por Albin me las hizo a titulo personal pero me dio la libertar de publicar la respuesta para que todos los de la lista la puedan leer y tal vez aclarar algunas dudas y (lo que seria mejor) aportar algunas otras consideraciones.

Dicho la anterior y sugiriendo que lean primero el e-mil de Albin (a pie de este mail) paso a responder y aclarar:

 Sistema de N-capas o "N-Tier systems" (por su nomenclarura en Ingles) : Un sistema N-capas basicamente se encarga de distribuir las diferentes servicios de un sistema en diferentes computadoras u ordenadores, incluyendo sistemas donde el Internet es un medio de enlace.
Un sistema tipico de N-tier es el WEB, asi el "user service" estaria encargado a los "Browsers" en las computadoras alrededor del mundo (primer Tier), el "Business services" estaria encargado a los WEB servers (IIS, apache, etc) (segundo Tier) y un "Data Service" estaria encargado a los "Data Centers" (MS-SQL, Oracle, MySQL, etc).
este seria un tipico 3-Tier system.
Sin embargo facilemente podrian incrementarse otros tipos de servicios en diferentes computadoras que harian del sistema un generico N-tier system o sistema de N-capas , podriamos tal vez pensar en un MTS Server (que se encargaria de administrar transacciones para efectos de integridad de data ademas de ser un magnifico administrador de "concurrencias" para optimizar la performace del sistema), o de MSQUE (administrador de colas de trabajos) Site Server ( e-comerce), Mail servers, etc.
Cuando uno trabaja solamente en una maquina (Stand alone) entonces se tiene un sistema de 1 capa o 1 Tier system, si por el contrario trabajamos en un systema "Cliente/servidor" (el mas difundido actuamente) que implica el uso de Una estacion de trabajo y un servidor de Data (Access o SQL o Oracle) a traves de queries o Store Procedures entonces estaremos hablando de un sistema de 2 Capas o 2-Tier system, que repito es el mas difundido aun en todo el planeta aunque con el advenimiento de la internet los sistemas N-Tier estan creciendo rapidamente.

De lo anterior, Albin, deduciras que no hay diferencias entre ADO y sistemas "Cliente/Servidor" ya que son conceptos que no se pueden comparar. ADO es una Objeto del tipo ActiveX que nos serve para poder acceder a la data. Lo moderno de ADO es que no se limita a la data tipica de Bases de Datos relacionales o ISAM (Access, SQL, Oracle, etc) sino que tambien se puede facilmente acceder a data tan disimiles como e-mail data, Index data , etc. la unica condicion es que exista un "provider" (data consumer) que pueda "enteder" la estructura de la data a leer y nos la entrege en formato de "Redorset" para nuestra "manipulacion". Sistemas "Cliente/servidor" como
mencione arriba es una manera de diseñar un sistema de tal manera que las diferentes labores de dicho sistema se distrubuyan en al menos dos Computadoras separadas fisicamente.

Lo que puede haberte confundido es el hecho que con un recorset de ADO puede en el lado del cliente hacer cierta validacion logica para la integridad de la data cuando este es el trabajo tipico del servidor de data en un sitema "Cliente/servidor" o del "Business Server" en un tipico N-Tier System.

ADO en absoluto necesita de ODBC para poder trabajar, por el contrario ADO nacio (ente otras cosas) para evitar en lo posible el uso de ODBC pues este es muy costoso en terminos de eficiencia. ODBC fue creado para acceder en lo posible a cualquier tipo de data siempre y cuando seta del tipo Base de Dato Relacional, mietras ADO (y en especifico OLE-DB) ha nacido para acceder a cualquier tipo de data (Universal Data Access de Microsoft) incluido, claro esta, las bases de dato relacionales.

Como cosa adicional ADO tambien permite acceder a bases de dato a traves de ODBC, sobre todo para aquellos tipos de datos que pudiendose acceder a traves de ODBC no existe un "provider" especifico de OLE-DB, de tal manera que ADO debera hacer uso de un "ODBC provider" para acceder a ella.

Debo aclararte que efectivamente ODBC no solo se encarga de darle el "Path" a una aplicacion para el acceso a la data sino que "standariza" el lenguaje de acceso a la misma (SQL Language) ademas de normar algunas reglas de seguridad. ADO y OLE-DB tambien norman ese lenguaje pero no se limitan a bases de datos Relacionales.

La capacidad que tienen Ciertas bases de datos de permiter acceso simultaneo a su data es inherente a ella misma y no a la capacidad de Windows ni al Uso de ODBC u OLE-DB para su acceso.

Respecto al bloqueo del tipo "Read Only", esto signifca que el recorset que se ha abierto solo puede ser usado para "leer" la data mas no para modificarla, esto se refiere al usuario o rutina o programa que hara uso de ese recorset. Mientras este usuario esta leyendo esa data, cualquier otro usuario o rutina u otro programa podra acceder a esa data y manipularla.

La ventaja de Read Only es que consume pocos recursos del sistema y si uno sabe de antemano que solo se quiere la data para consulta lo mejor sera usar ese bloqueo y, si ademas solo queremos la data para mostrarla (en un grid por ejemplo), efectivamente lo mejor sera abrirla "forward Only" y poblar el grid. Pero se me ocurre que podriamos querer usar al menos adOpenStatic en circunstancias donde no haya algun control donde preservar la data y querramos "pasearnos" por ella de manera dinamica (ADO trabaja
magnificamente con recorset desconectados y siempre es del tipo Static y del lado del cliente).

El Bloqueo pesimista garantiza que el record activo o en edicion en el cursor estara bloqueado para cuanquiera otro que pretenda usarlo, pero este se liberara al mover el cursor a otro record o cuanbdo se cierra el recorset. Pero estate claro que solo se refiere al registro en edicion no a todo el recorset.
Read only, como viste anteriormente, es todo lo contrario, no bloquea absolutamnte nada ya que no es posible la edicion de la data.

Lo que permite Keyset es registrar los cambios hechos por otros usuarion o programas a la data que actualmente tiene el recorset (pero solo las modificiones, no las adiciones o borrados hechos por otros). de tal manera que el valor de un record puede ser digamos 10 al momento de abrir el recorset, pero si otro programa u otro usuario lo cambia a 12 entonces ese cambio se reflejara en el recorset abierto por el primero, es decir el 10 se convertira en 12

Dynamic tambien refleja las adiciones y Borrados hechos por otros programas
o usuarios. Estos dos ultimos tienen un alto costo en terminos de usos de recursos.

En el caso de Static, donde no se refleja en el recorset los valores "variados" de un recorset como es Keyset o Dynamic, puedes, efectivamente, usar las propiedas Field.value, Field.OriginalValue y Field.UnderlayinValue, para comparar si hay variaciones y tomar diciciones de que hacer en ese caso.

En un recorset que no es ReadOnly el record que esta activo esta siempre en edicion, no necesita indicarse que se hara una edicion. Lo que si hay es una propiedad EditMode que te indica que tipo de "edicion" se ha hecho en el recorset (borrado, adicionado, editado en si o ninguna edicion).

Respecto a si cambiar a VB6 o no mi respuesta final seria Si, hace unos meses me preguntaron algo parecido y conteste que si ya que VB6 con su SP3 esta suficiente maduro para confiar en el. En tu caso veo que trabajas basicamante en sistemas "Stand Alone" no en sietemas en Red o Multiusuarios, ahi no veras gran ventaja. Pero si por el contrario decides empezar a programar en ADO en sistemas N-Tier o en sistemas de Internet, entonces VB6 tiene algunas herramientas de desarrollo que VB5 no posee (ademas de algunas funciones adicionales com Replace, split, etc que VB5 no tenia). Ademas hay algunos controles que hacen uso de ADO de una manera mas efeciente (ADODC,
etc).

Bueno, lo anterior es bastabte grande, espero que sirva de ayuda

Saludos

Oswaldo



> > -----Original Message-----
> > From: Un habitante de este Universo [mailto:albin@arrakis.es]
> > Sent: Monday, January 10, 2000 11:15 AM
> > To: Oswaldo D'Acevedo
> > Subject: ADO ... Cursores, Bloqueos.
> >
> >
> >
> > Saludos,
> >
> > Cuando enviaste tu colaboración a modo de tutorial sobre ADO la guardé
> > automaticamente porque sabía que acabaría usandola, desde luego ha sido
> muy
> > util, ten en cuenta que solo sabía que ADO existía y que algo hacia
> > parecidito al DAO que usaba yo... Gracias majete, pero...
> >
> > Hay varias explicaciones que no me quedan claras, y otras que son pura
> > duda:
> > - ¿Que es un sistema N-Capas?
> > - ¿Que diferencia hay entre ADO y un sistema Cliente/Servidor?
> > - ¿ADO implica que estoy usando ODBC? ¿ODBC implica algo mas que, en
lugar
> > de decirle el Path de mi base de datos, configurarla en el Panel de
> Control
> > del Windows y luego hacer referencia a esa configuración? ¿La utilidad
> > reside en que varios ordenadores podrian abrir esta base de datos con
este
> > metodo y el Windows se encargaria de dar soporte a todos, digamos, a
hacer
> > de Servidor para esos clientes?
> >
> > - Si abro un RecordSet con bloqueo ReadOnly comentas que el/los
registro/s
> > solo pueden ser accedidos para leer datos ¿Por quien/que? ¿Por otros
> > RecordSets, de modo que pueden consultar, pero no pueden tocar hasta que
> yo
> > no haya acabado mis actualizaciones? ¿O tampoco este RecordSet puede
> > modificar datos? Porque de ser así, no vale la pena usarlo salvo en
> > Cursores Forward Only ¿O si merece la pena en otros, pero no he pensado
en
> > qué situacion podría ser interesante?
> > - Si abro un RecordSet con bloqueo Pesimista ¿Ningun otro RecordSet
podrá
> > obtener ningun tipo de informacion sobre los registros que este útilice?
> > ¿Entonces como pueden saber si no existe un cliente o es que esta siendo
> > bloqueado pesimistamente? ¿No se puede acceder para consultar? Si es que
> si
> > ¿Que diferencia hay con el ReadOnly?
> > - Los cursores de tipo KeySet y Dynamic según cuentas permiten saber si
ha
> > habido alguna modificación ¿Hacen saltar algun evento? Bueno, esto ya se
> > que no pero ¿Como puedo saberlo para actualizarlo en Tiempo Real? Si no
se
> > puede ¿Que diferencia hay pues con un Static y sus propiedades
> > Field.OriginalValue & Field.UndelayinValue?
> >
> > Lo que sucede, es que he estado haciendo pruebas de como se comporta
segun
> > lo que hago, y segun lo que he definido, y no entiendo de que me sirve
> > decirle "solo voy a leer" (ReadOnly) para que me bloquee el escribir,
> > cuando no pensaba hacerlo, y cuando de todos modos, aunque yo le dijera
> > "Igual escribo algo" (Pesimista) el va a seguir dejando a los demas que
> > escriban.
> >
> > He añorado el recordset.Edit ¿No existe o ahora se llama de otro modo?
> >
> > Si voy a usar ADO ¿Me recomiendas mudar a V.B. 6.0? Hago un poco de
pereza
> > porque solo de pensar que podría necesitar el SP3, y lo que ocupa, me
> > tiemblan las piernas.
> >
> > Como de costumbre, si crees que la consulta puede ser útil para mas
> > personas (osea que no soy tan tonto sino que tengo dudas razonables)
pues
> > enviame la respuesta por la lista, y adjunta mis dudas para que
comprendan
> > tus comentarios.
> >
> > Gracias por antenderme. Un abrazo,
> > albin@arrakis.es
>
>



Resumen Resumen

Visual Basic Página de Visual Basic

Página principal Página principal

www.jrubi.com