Bloqueo en intranet

74 views
Skip to first unread message

Antonio Cardinaux

unread,
Sep 21, 2020, 2:03:21 PM9/21/20
to ADO Harbour
Una consulta David. Si estoy en una intranet (Windows Server por ej.) y quiero modificar un registro de una tabla determinada,¿Tengo que bloquear el registro que quiero modificar antes de hacerlo?, ej.

oRs:=Ado( "SELECT campo1,campo2 FROM tabla1 WHERE campo1='1'",oC)
      
while !oRs:Eof()
  oRs:Fields("campo1"):value:='55'
  oRs:MoveNext()
end whil

Para hacer algo así en un ambiente de red, hay que bloquear ese registro de alguna forma?

Antonio
Sistemas
Resipol

Nippur Lagash

unread,
Sep 21, 2020, 2:53:49 PM9/21/20
to ado-h...@googlegroups.com
Hola Antonio, quizas pusiste el while a modo de ejemplo, pero lo reemplazaría por un:
UPDATE tabla1 SET campo1 = 55 WHERE condicion1

Si estás usando mysql no es necesario bloquear nada, de eso se ocupa el motor.
En caso de dbf, usaría el rlock.

Saludos,
Fer.MDQ



--
Has recibido este mensaje porque estás suscrito al grupo "ADO Harbour" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a ado-harbour...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/ado-harbour/fcbcaf86-86f0-4876-93ad-35003fb51db2n%40googlegroups.com.


--
Nippur
Mar del Plata
Buenos Aires
Argentina

Antonio Cardinaux

unread,
Sep 21, 2020, 3:06:46 PM9/21/20
to ado-h...@googlegroups.com
Hola Fer. Si lo puse como un ejemplo porque quizás estoy muy acostumbrado a usar DBF, pero me sirve saber esa segunda opción y saber que no necesita bloqueo. Muchas Gracias.



--
Antonio Cardinaux - Lanús - Pcia. de  Buenos Aires - Argentina

David Field

unread,
Sep 23, 2020, 4:52:38 PM9/23/20
to ADO Harbour
Hola,

Solo con el propósito de aclarar algunas cosas acerca de bloqueos en SQL
1. Los motores SQL manejan el bloqueo de forma automática.
2. sin embargo ADODB permite que especifiques 4 tipos de bloqueo que puedes especificar en el :LockType del recordset
1 adLockReadOnly 
2 adLockPessimistic, 
3 adLockOptimistic, 
4 adLockBatchOptimistic

La clase DBADO() provista por mi utiliza adLockBatchOptimistic

3. El bloque NO ocurre a la hora de asignar valores a los campos, si no a la hora de escribir (actualizar/Update) del recordset a menos que modifiquen o utilicen un :CursorLocation := adUseServer
La clase DBADO() provista por mi utiliza :CursorLocation := adUseClient

4. Aun con todo esto, me he encontrado con la necesidad de saber si alguien más está realizando algún cambio al registro. Por ejemplo: Tienes un registro de cliente y deseas modificar la dirección, pero, pudiera ser que alguien más estuviera modificando el mismo u otro dato al mismo tiempo, digamos el teléfono.
Originalmente a ambos la pantalla les presentará la misma información
Direccion = Calle Olmos 123, Telefono = 999 123 4567
Usuario 1 modifica la dirección a Calle Olmos 456 y guarda, sin embargo para usuario 2 su recordset aun tiene el dato de Calle Olmo 123, este cambia el teléfono y guarda y esta será la información a final de cuentas registrada por lo que se pierde la modificación de la dirección.
ADO notifica al segundo usuario que la información contenida en su recordset ya no es válida, siempre y cuando se haya solicitado el campo modificado por el primer usuario, pero esto genera un error al usuario y al programador.

Yo he recurrido a una artimaña donde creo una tabla llamada Reclock con campos:
tabla = pongo el nombre de la tabla a bloquear
registro = id del registro a bloquear
usuario = clave del usuario que tiene el registro
Esta tabla está indexada por tabla+registro y definido que deben ser únicos

Cuando un usuario entra a editar un registro, llamo a la función que escribe los datos a la tabla Reclock y si esta no regresa error es que no existe nadie que esté usando el registro, si da error, entonces envío mensaje al usuario de que está en uso por alguien más (aquí se puede utilizar la clave de usuario para identificar quien lo está usando)

Obvio, cuando el usuario abandona la edición, ya sea por que guardó los datos o canceló la edición, borro el registro de Reclock.
Igualmente al salir el usuario, borro de la tabla Reclock todos los registros del usuario (solo por si acaso)

Saludos,
David Field

Sergio Castellari [Gmail]

unread,
Sep 24, 2020, 7:45:21 AM9/24/20
to ado-h...@googlegroups.com

Hola gente…hola David,

 

Como siempre (y agradecido) dándonos excelentes explicaciones bien detallada, tomándote mucho tiempo para darnos esos detalles (tan valiosos para tantos colegas).

Con respecto a tu “artimaña” (propia de una programación experimentada en SQL), Yo utilizo una técnica similar, pero en lugar de ser a nivel registro (máximo control), lo hago a nivel “comercial”, es decir, tengo una tabla auxiliar también, pero en este caso  “guardando” el código del Cliente, o Proveedor, o Cta.Cte que se este “editando” en ese momento…para evitar temporalmente la edición de otro usuario con el mismo objeto comercial. Esa tabla guarda también el nombre de la PC y el Usuario, de esta forma puedo “informar” detalles cuando alguien quiere acceder al mismo para edición.

 

Saludos,

Sergio Castellari

Victor Casajuana Mas

unread,
Sep 24, 2020, 8:05:51 AM9/24/20
to ADO Harbour
Hola a todos!

Este sistema de bloqueos me parece estupendo para tener información de quien, que y cuando está modificando algo, pero que pasa si por algún motivo hay apagón, se cae el sistema o salta un error y no se pueden borrar los registros?

se queda la tabla con esos registros y ya no se borran? o al entrar el usuario de nuevo se inicializan sus registros de bloqueo?

Saludos.!

Antonio Cardinaux

unread,
Sep 24, 2020, 8:33:17 AM9/24/20
to ado-h...@googlegroups.com
Muy clara David la explicación, me gustó tu "artimaña". Una consulta, cuando dices "clave del usuario que tiene el registro" a que te refieres?, a la clave de ingreso a, por ej. MySQL, o a algún otro tipo de clave.

Has recibido este mensaje porque estás suscrito a un tema del grupo "ADO Harbour" de Grupos de Google.
Para cancelar la suscripción a este tema, visita https://groups.google.com/d/topic/ado-harbour/C2pDCc_-l2g/unsubscribe.
Para cancelar la suscripción a este grupo y a todos sus temas, envía un correo electrónico a ado-harbour...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/ado-harbour/01b8853d-5604-4f5e-bddc-ba5fed37537dn%40googlegroups.com.

Sergio Castellari [Gmail]

unread,
Sep 24, 2020, 8:37:06 AM9/24/20
to ado-h...@googlegroups.com

Hola Victor!,

 

En mi caso…si hubiere una apagón local (mi sistema reside en la nube), tengo 2 métodos para “eliminar” registros que pudieran quedar colgados:

1.       El propio usuario vuelve a entrar al sistema, el sistema al entrar “revisa” la tabla auxiliar y si encuentra registros a SU nombre…los elimina automáticamente…

2.       Si el usuario NO volviera a entrar, tengo configurado en el proceso que después de 20 minutos de “antigüedad” libere el registro en cuestión. Este tiempo se puede configurar desde el sistema, según observe el entorno de operadores…

 

El método no es perfecto, y seguramente deben existir ideas mejores, pero desde que lo implemente (hace como 4 años) nunca tuve problemas de sobreescribir campos en una ficha. El mayor riesgo se daba en las cargas de “pagos” a proveedores o “cobranzas” a clientes, que debido a la naturaleza de la nube y sucursales con los “mismos” clientes y clientes que a su vez admitían mas de un familiar o empleado a cancelar deudas.

Son situaciones MUY especificas y muy poco comunes. En mi opinión, el 99.5% de los casos no requieren estos controles…

Un caso similar, aplico para la emisión de Facturas Electrónicas (Argentina), ya que para un mismo Punto de Venta y Tipo de Comprobante, la AFIP no te garantiza la  correlatividad en solicitudes concurrentes.

Miguel Ingles

unread,
Sep 24, 2020, 2:00:08 PM9/24/20
to ado-h...@googlegroups.com
Hola a todos

Yo utilizo otro tipo de formato:

En la tabla de cliente creo un campo "bloqueo TINYINT UNSIGNED DEFAULT 0"
Cuando leo el registro o un campo, incluyo el campo bloqueo
En el momento de guardar comparo el campo bloqueo con el de la base de datos, 
si es distinto, doy un mensaje de error
Si es igual guardo los datos incluido el campo "bloqueo = hb_RandomInt(0, 255)"

Espero que os sirva

Saludos
Miguel



David Field

unread,
Sep 24, 2020, 3:28:09 PM9/24/20
to ADO Harbour
Antonio,
En mis sistemas, se requiere crear usuarios con contraseñas para acceder al sistema y definir sus permisos.
No tiene nada que ver con el usuario y contraseña de MySql para acceder a la base de datos.

Muy parecido al usuario y contraseña de MySql pero a nivel sistema.

Victor,
El sistema actualiza cada 90 segundos (me pareció un tiempo adecuado) un campo de fecha y hora a una tabla que contiene la clave de usuario.
Esta tabla me sirve para varios propósitos:
1. Saber cuantos usuarios están utilizando el sistema
2. Si la fecha y hora actual es mayor a 100 segundos de la fecha y hora registrada en el campo, me indica que por alguna razón ese usuario salió del sistema de forma no controlada (apagón, error del sistema, falla de internet, etc). En este caso borro todos los registros de bloqueo de ese usuario.
3. Suponiendo el caso anterior y el usuario vuelve a entrar al sistema, de todas formas se eliminan los bloqueos que haya tenido anteriormente y se volverán a imponer una vez entre a editar.

Saludos,
David Field

Antonio Cardinaux

unread,
Sep 24, 2020, 4:38:59 PM9/24/20
to ado-h...@googlegroups.com
Se entendió perfecto David. Gracias.

Antonio Cardinaux

unread,
Sep 24, 2020, 4:44:01 PM9/24/20
to ado-h...@googlegroups.com
Una cosa que veo muy común entre los usuarios del sistema de donde trabajo es que abren dentro del mismo puesto varias instancias de la aplicación. En ese caso se complicaría manejar los bloqueos por usuario, ya que al ingresar de nuevo a la aplicación se borrarían los bloqueos actuales de ese usuario en la otra instancia que está usando.

Nippur Lagash

unread,
Sep 24, 2020, 7:50:28 PM9/24/20
to ado-h...@googlegroups.com
Hola, no se para que se enroscan con algo que lo resuelve el motor de base de dstos, para agregar consistencia de datos con utilizar transacciones es suficiente.

Saludos!
Fer.MDQ

David Field

unread,
Sep 24, 2020, 11:51:15 PM9/24/20
to ADO Harbour
Antonio,
Eso es MUY común en todos lados, los usuarios tienen abierto su browser, whatapp, música, etc. y he visto que a todos les encanta tener todo MAXIMIZADO y son FLOJOS por lo que si no ven enseguida tu aplicación les es fácil volver a dar doble click sobre el link.

Yo tengo programado dentro de mis sistemas que verifique que no haya otra instancia del programa en ejecución, en caso de que si lo haya, el mismo programa trae al frente la instancia anterior y se cierra.

   hb_FNameSplit( hb_progname(), @cPath, @cProgName, @cProgExt )
   IF IsExeRunning( cProgName+cProgExt )           // Si el programa ya está corriendo 
      If (hWnd := FindWindow("nombre_que_le_hayas_puesto_al_Main")) <> 0    // encontrar hWnd
eg: DEFINE WINDOW dSign MAIN...
         IF ISWINDOWMINIMIZED( hWnd )              // Si está minimizado
            Restore( hWnd )                        // Restaurar
         ELSE
            SetForeGroundWindow( hWnd )            // Traer al frente
         ENDIF
        Return  //salgo del ejecutable
   Endif
Endif

Por ahí Sergio comentó en algún post que OOHG tiene una forma de hacer esto, ojalá la comparta aquí.

Fer,
Estoy de acuerdo contigo que las transacciones son para grabar todo o nada, sin embargo, personalmente no me gusta que el usuario pierda su tiempo realizando cambios que no se van a poder grabar por inconsistencia de datos.
Es MUY raro que ocurra esto, y nunca he tenido a un cliente quejarse por que no ha podido modificar un registro que alguien más tenga en uso, pero es una posibilidad y prefiero prevenir que arreglar.

A final de cuentas, tiene mucho que ver con el estilo de programar y cómo cada quien desee hacer las cosas.

Saludos,
David Field

Sergio Castellari [Gmail]

unread,
Sep 25, 2020, 9:06:43 AM9/25/20
to ado-h...@googlegroups.com

Hola gente,

 

ooHG tiene la siguiente instrucción para evitar instancias multiples de un ejecutable:

 

Set Multiple Off Warning 

 

Fernando Nippur (mi maestro de MySQL):

Claro que los motores tienen transacciones que hacen “todo” automático para guardar la data y su integridad…pero de lo que se habla aquí (el ejemplo de David) y lo que creo “que entendí”, son las REBLAS de NEGOCIO…entonces…si existen dos operadores sobre una misma cuenta corriente (por ej.), y ambos están cargando Pagos….obviamente que la transacción se encargará de guardar la data con integridad…pero la ultima transacción (de las dos) pisará la primera…y por lo tanto la regla de negocio fallará (aunque la DB mantenga integridad). Para ESOS casos, es donde tenes que aplicar alguna técnica que EVITE pisar datos (información) que mantiene la integridad de la operación “comercial”.

 

Saludos totales,

Sergio Castellari

 

 

 

 

 

 

 

De: ado-h...@googlegroups.com [mailto:ado-h...@googlegroups.com] En nombre de David Field
Enviado el: viernes, 25 de septiembre de 2020 12:51 a.m.
Para: ADO Harbour
Asunto: Re: [ADO Harbour] Bloqueo en intranet

 

Antonio,

Reply all
Reply to author
Forward
0 new messages