Foros del Web » Programación para mayores de 30 ;) » Programación General » Visual Basic clásico »

bloquear tabla y registros

Estas en el tema de bloquear tabla y registros en el foro de Visual Basic clásico en Foros del Web. Alguien que me de una mano: Estoy trabajando con una tabla de mysql a la cual accedo desde vb6 con odbc, el tema es que ...
  #1 (permalink)  
Antiguo 14/03/2011, 16:40
 
Fecha de Ingreso: agosto-2007
Mensajes: 66
Antigüedad: 17 años, 2 meses
Puntos: 0
bloquear tabla y registros

Alguien que me de una mano:
Estoy trabajando con una tabla de mysql a la cual accedo desde vb6 con odbc, el tema es que quiero dos cosas:
una rutina donde pueda tomar posesion de una tabla y que nadie pueda acceder hasta que la libere.
Y otra rutina donde pueda tomar solo un registro y nadie pueda acceder a ese registro hasta que lo libere
Gracias al que me pueda dar una mano
  #2 (permalink)  
Antiguo 16/03/2011, 12:03
Avatar de lokoman  
Fecha de Ingreso: septiembre-2009
Mensajes: 502
Antigüedad: 15 años, 1 mes
Puntos: 47
Respuesta: bloquear tabla y registros

En la BD crea una tabla de "Estado_Bloqueo_Tabla" y "Estado_Bloqueo_Registro", Con los campos que necesites para identificar el bloqueo (usuario, nombre_tabla, fecha, Documento_Registro, etc.), desde tu aplicación puedes hacer lo que quieras:

• Antes de acceder a la tabla o modulo que puede o no estar bloqueado, consultas la tabla "Estado_Bloqueo_Tabla" o "Estado_Bloqueo_Registro" según el caso:
• Si te trae datos, pues está en uso por otro usuario
• Si no trae datos, pues inserta los datos correspondientes en la tabla que consultaste y continua con el acceso a la tabla o modulo en tu aplicación.
• Al terminar de trabajar con la tabla o modulo (que ya esta en uso por el usuario), limpias la tabla que consultaste y cierras la conexión, recodset, bloqueas los campos, cierras el Form, etc.

El punto es que estas tablas siempre que no estén en uso, se encuentren sin datos, asi puedes restringir el acceso a las tablas !!

Inténtalo y nos cuentas!!
  #3 (permalink)  
Antiguo 16/03/2011, 15:31
 
Fecha de Ingreso: agosto-2007
Mensajes: 66
Antigüedad: 17 años, 2 meses
Puntos: 0
Respuesta: bloquear tabla y registros

Cita:
Iniciado por lokoman Ver Mensaje
En la BD crea una tabla de "Estado_Bloqueo_Tabla" y "Estado_Bloqueo_Registro", Con los campos que necesites para identificar el bloqueo (usuario, nombre_tabla, fecha, Documento_Registro, etc.), desde tu aplicación puedes hacer lo que quieras:

• Antes de acceder a la tabla o modulo que puede o no estar bloqueado, consultas la tabla "Estado_Bloqueo_Tabla" o "Estado_Bloqueo_Registro" según el caso:
• Si te trae datos, pues está en uso por otro usuario
• Si no trae datos, pues inserta los datos correspondientes en la tabla que consultaste y continua con el acceso a la tabla o modulo en tu aplicación.
• Al terminar de trabajar con la tabla o modulo (que ya esta en uso por el usuario), limpias la tabla que consultaste y cierras la conexión, recodset, bloqueas los campos, cierras el Form, etc.

El punto es que estas tablas siempre que no estén en uso, se encuentren sin datos, asi puedes restringir el acceso a las tablas !!

Inténtalo y nos cuentas!!
gracias Lokoman por la idea que me tiras, no es mala, seria una forma manual de hacerlo, aunque el ultimo punto que mencionas no lo entendi ya que hablas en él de bloquear campos cuando terminas de usar la tabla, si termine de usarla para que bloqueo los campos ¿?. Y de hecho de eso se trata, como bloqueo?
No obstante creo que debe haber una forma automatica cuando se abre la conexion y definimos el locktype en adLockOptimistic. De hecho creo que la documentacion asi lo explica, pero lo intente y mientras tengo abierta la conexion con este tipo de lokeo me deja acceder al registro lo mas bien, cuando necesitaria que me genere un error impidiendome el acceso
  #4 (permalink)  
Antiguo 16/03/2011, 16:41
Avatar de culd  
Fecha de Ingreso: noviembre-2003
Mensajes: 959
Antigüedad: 21 años
Puntos: 19
Respuesta: bloquear tabla y registros

TuRecordSet.Open "TU CODIGO SQL", TuConexion, adOpenDynamic, adLockPessimistic

Con eso hasta que no se libere no deja hacer nada.
  #5 (permalink)  
Antiguo 17/03/2011, 08:34
Avatar de lokoman  
Fecha de Ingreso: septiembre-2009
Mensajes: 502
Antigüedad: 15 años, 1 mes
Puntos: 47
Respuesta: bloquear tabla y registros

Con lo del "Bloqueo de los campos" que mencioné, me referia a algo como esto:
Código vb:
Ver original
  1. Textbox.enabled=False
  2. 'O DE ESTA FORMA
  3. Textbox.Locked=True



Los Locktype:

adLockReadOnly - default type used when no locktype is specified
adLockPessimistic - forces the database to lock the entire record when editing first starts
adLockOptimistic - locks records only after you call the UPDATE method of the recordset object
adLockBatchOptimistic - allows batch updating instead of updating each record individually
---------------------------------------------------------------
adLockReadOnly - default si no se especifica
adLockPessimistic - obliga a la base de datos bloquear el registro cuando se comienza a editar
adLockOptimistic - bloquea los registros solo despues que usas UPDATE en el recordset
adLockBatchOptimistic - peromite actualizar por lotes en vez de actualizar los registros individuales

Pero creo esto no bloquea la tabla...
  #6 (permalink)  
Antiguo 17/03/2011, 08:48
 
Fecha de Ingreso: agosto-2007
Mensajes: 66
Antigüedad: 17 años, 2 meses
Puntos: 0
Respuesta: bloquear tabla y registros

Cita:
Iniciado por lokoman Ver Mensaje
Con lo del "Bloqueo de los campos" que mencioné, me referia a algo como esto:
Código vb:
Ver original
  1. Textbox.enabled=False
  2. 'O DE ESTA FORMA
  3. Textbox.Locked=True



Los Locktype:

adLockReadOnly - default type used when no locktype is specified
adLockPessimistic - forces the database to lock the entire record when editing first starts
adLockOptimistic - locks records only after you call the UPDATE method of the recordset object
adLockBatchOptimistic - allows batch updating instead of updating each record individually
---------------------------------------------------------------
adLockReadOnly - default si no se especifica
adLockPessimistic - obliga a la base de datos bloquear el registro cuando se comienza a editar
adLockOptimistic - bloquea los registros solo despues que usas UPDATE en el recordset
adLockBatchOptimistic - peromite actualizar por lotes en vez de actualizar los registros individuales

Pero creo esto no bloquea la tabla...
Gracias LOKOMAN por la aclaracion, justamente uso la opcion adLockPessimistic, pero cuando hago la conexion no me deberia bloquear la lectura del registro hasta que no cierre la conexion???? y sí, esto supuestamente bloquearia solo registro y no tabla pero no deberia existir algo automatico que me bloquee la tabla??? asi evito hacer la rutina que me das como ejemplo
GRACIAS

Última edición por g_cury; 17/03/2011 a las 09:00
  #7 (permalink)  
Antiguo 17/03/2011, 09:14
Avatar de lokoman  
Fecha de Ingreso: septiembre-2009
Mensajes: 502
Antigüedad: 15 años, 1 mes
Puntos: 47
Respuesta: bloquear tabla y registros

Creo que lo que hace es bloquear el registro SOLO la EDICION... osea, que dos personas no pueden editar el mismo registro a la vez, pero una de ellas si puede leer (la data vieja) mientras el otro edita (data nueva) hasta que se guarden los datos...
Existe un parametro (LOCK) para las sentencias SQL pero nunca las he usado
  #8 (permalink)  
Antiguo 17/03/2011, 09:18
 
Fecha de Ingreso: agosto-2007
Mensajes: 66
Antigüedad: 17 años, 2 meses
Puntos: 0
Respuesta: bloquear tabla y registros

Cita:
Iniciado por lokoman Ver Mensaje
Creo que lo que hace es bloquear el registro SOLO la EDICION... osea, que dos personas no pueden editar el mismo registro a la vez, pero una de ellas si puede leer (la data vieja) mientras el otro edita (data nueva) hasta que se guarden los datos...
Existe un parametro (LOCK) para las sentencias SQL pero nunca las he usado
Pense lo mismo, debe bloquear solo la edicion, pero tendria que haber alguna forma que bloquee totalmente el registro ya que si necesito procesar el ultimo numero de una tabla dos usuarios agarrarian el mismo numero como ultimo y me generaria un numero duplicado al actualizar
Lo del LOCK en sql no lo probe, ya me pongo a hacerlo
  #9 (permalink)  
Antiguo 17/03/2011, 09:41
Avatar de lokoman  
Fecha de Ingreso: septiembre-2009
Mensajes: 502
Antigüedad: 15 años, 1 mes
Puntos: 47
Respuesta: bloquear tabla y registros

Eso lo puedes controlar al momento de guardar los datos, usa la instruccion:

Código SQL:
Ver original
  1. rs.OPEN "SELECT MAX(NUMERO) AS NUMERO_A_GUARDAR FROM NOMBRE_TABLA"

Te traerá el ultimo numero, entonces:
Código vb:
Ver original
  1. varNumero=rs!NUMERO_A_GUARDAR +1
  2.  
  3. 'GUARDAS TUS DATOS
  4. Cnn.Execute="Insert into Tabla (Campo1, Campo2, Numero) values ('bla','bla bla'," & varNumero & ")"
  5.  
  6. 'ACTUALIZAS LA TABLA QUE TIENE EL NUMERO DE SECUENCIA CON EL ULTIMO NUMERO USADO
  7. Cnn.Execute="Insert into NOMBRE_TABLA (NUMERO) values (" & varNumero & ")"
  #10 (permalink)  
Antiguo 17/03/2011, 09:59
 
Fecha de Ingreso: agosto-2007
Mensajes: 66
Antigüedad: 17 años, 2 meses
Puntos: 0
Respuesta: bloquear tabla y registros

Cita:
Iniciado por lokoman Ver Mensaje
Eso lo puedes controlar al momento de guardar los datos, usa la instruccion:

Código SQL:
Ver original
  1. rs.OPEN "SELECT MAX(NUMERO) AS NUMERO_A_GUARDAR FROM NOMBRE_TABLA"

Te traerá el ultimo numero, entonces:
Código vb:
Ver original
  1. varNumero=rs!NUMERO_A_GUARDAR +1
  2.  
  3. 'GUARDAS TUS DATOS
  4. Cnn.Execute="Insert into Tabla (Campo1, Campo2, Numero) values ('bla','bla bla'," & varNumero & ")"
  5.  
  6. 'ACTUALIZAS LA TABLA QUE TIENE EL NUMERO DE SECUENCIA CON EL ULTIMO NUMERO USADO
  7. Cnn.Execute="Insert into NOMBRE_TABLA (NUMERO) values (" & varNumero & ")"

Ok, haber si no te entendi mal, yo con esa sentencia traigo el ultimo_numero (ejemplo: 3547), ahora resulta que antes de actualizar el nuevo_ultimo_numero (3548) tengo que hacer algunos procesos. El PROBLEMA seria que si en el medio de esos procesos otro usuario ingresa y trae el ultimo_numero (3547) va a tener el mismo ultimo numero que yo, por lo que al momento de actualizar los dos tendriamos igual el mismo nuevo_ultimo_numero(3548). Por eso es que desde que yo tomo el ultimo_numero hasta que actualizo con el nuevo_ultimo_numero quisiera bloquear el registro para que nadie pueda ni siquiera consultar cual es el ultimo_numero, yo se que es cuestion de fraccion de segundos, pero el tema es que ese ULTIMO_NUMERO es usado para actualizar 5 tablas más.
Espero haber sido claro con la explicacion.
Desde ya gracias lokoman
  #11 (permalink)  
Antiguo 17/03/2011, 10:34
Avatar de lokoman  
Fecha de Ingreso: septiembre-2009
Mensajes: 502
Antigüedad: 15 años, 1 mes
Puntos: 47
Respuesta: bloquear tabla y registros

Ok... pues entonces al revés, en vez de guardar el numero al final, lo guardamos al inicio... algo así:

• Cuando de das clic al botón "Agregar Registro" obtienes el ultimo numero de la secuencia y le sumas uno, inmediatamente lo guardas en la tabla de secuencias de números y en una variable. Así cualquier usuario que ingrese obtendrá el numero siguiente al que guardaste.

• Como ya tienes un nuevo numero (que está en una variable) trabajas de lo mas normal con todas las tablas que necesites (basándote siempre en el numero que tienes en la variable), los otros usuarios van a estar trabajando con números menor o mayor que el que tienes pero nunca con el mismo numero que tienes, lo que evitará la duplicidad de números.

• Todos los procesos estarán en secuencia, pero trabajados por diferentes usuarios!! !!
  #12 (permalink)  
Antiguo 17/03/2011, 10:45
 
Fecha de Ingreso: agosto-2007
Mensajes: 66
Antigüedad: 17 años, 2 meses
Puntos: 0
Respuesta: bloquear tabla y registros

Disculpame que siga insistiendo, debo hacer todos los procesos bloqueando ese registro sin que lo puedan acceder hasta que no termine el 100% de los procesos. El tema es que si por algun motivo no se completan los procesos tengo que volver a dejar el mismo ultimo_numero que tenia en su principio y logicamente no podria hacerlo ya que a otro usuario ya le habria asignado otro ultimo_numero
  #13 (permalink)  
Antiguo 20/03/2011, 04:49
Avatar de Gakex  
Fecha de Ingreso: enero-2009
Mensajes: 137
Antigüedad: 15 años, 10 meses
Puntos: 4
Respuesta: bloquear tabla y registros

hay eso es algo muy fácil y ademas se lo dejas directamente al SGBD, eso que quieres hacer se llama realizar una "Transacción" y anteriormente hable de eso aquí en este foro que por cierto es algo que acabo de aprender y al parecer no hay mucha información de como hacerlo, por aquí, porque esto que te voy a contar lo tuve que experimentar.

Basicamente quieres evitar que un usuario modifique o lea un dato que estas a punto de modificar, por la rason de que la base de datos quedaria inconsistente, es decir, mmm... digamos que no cuadraria.

en el ejemplo de la compra de un boleto de autobus debemos primeramente ver cuales asientos estan disponibles y mostrarselos al cliente, el cliente decidira cual es el que mas le agrada, pero digamos que hay 5 personas en el mismo momento comprando boleto para ese viaje y dos de ellos quieren el mismo asiento, que pasaria si se vende dos veces el mismo lugar?
inconsistencia es la respuesta.
por ese motivo es necesario bloquear, no las tablas pero si, los registros y si el cliente A se decide por otro asiento pues simplemente se cansela la transaccion y regresa a su estado inicial asi el cliente B, C ó D podra comprar el boleto ocupando el asiento en disputa.

otro ejemplo donde tambien se deben hacer transacciones es para prevenir inconsistencias por falla electrica:
si imaginen que estan metiendo un nuevo registro en una tabla y ademas actualizan dos tablas mas y justamente cuando le estan dando click para guardar el registro en una milesima de fraccion de segundo se va la luz y se apaga el disco duro y la computadora, si solo se ejecuto la mitad del proceso, las dos tablas no se actualizaron y la base de datos quedo inconsistente, se puede arreglar a mano pero si ademas es multi usuarios y muchos la usan pta nunca terminas tu solo.
esto se pudo haber evitado si hubieras usado transacciones, ahora imagina que se va la luz que alimenta al servidor de un banco, que es imposible pero....

Bueno, como se hace esto

usando los metodos:
BeginTrans antes de ejecutar las cadenas sql y terminas con CommitTrans

y haciendo referencia al primer ejemplo digamos que el usuario A se retracta de compra el boleto, entonces pasamos un RollbackTrans.

espero haber sido claro cya.
  #14 (permalink)  
Antiguo 20/03/2011, 07:01
 
Fecha de Ingreso: agosto-2007
Mensajes: 66
Antigüedad: 17 años, 2 meses
Puntos: 0
Respuesta: bloquear tabla y registros

Gracias Gakex por tu interes en darnos luz al problema y me parece que son las Transaciones la solución. Pero para que todos podamos ahorrar tiempo y enriquecer nuestros conocimientos (que para eso son los foros) por que no subis un ejemplo, pero en codigo de programacion VB6 asi nos ahorramos estar al tun tun.
gracias
  #15 (permalink)  
Antiguo 20/03/2011, 11:44
Avatar de Gakex  
Fecha de Ingreso: enero-2009
Mensajes: 137
Antigüedad: 15 años, 10 meses
Puntos: 4
Respuesta: bloquear tabla y registros

Si claro mira yo concretamente uso adodb que es un controlador de base de datos el motor es Microsoft.Jet.OLEDB.4.0 y obviamente uso access 2003, aunque no es lo mismo debe funcionar parecido.

al final decidí poner un ejemplo sencillo para no complicarte mucho la explicación, este es uno de mis procedimientos de un sistema que hice hace poco, y este es solo para prevenir la inconsistencia por falla eléctrica o desconección.

Código:
Public CNN As New ADODB.Connection
Public RST As New ADODB.Recordset
Public PRV As String
Public SQL1 As String

Function asg() 
PRV = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & frmMain.SourceDB & ";Persist Security Info=False"
End Function
Código:
Sub AgregarNuevoCliente()
    call asg
    CNN.Open PRV    '<{----{ Abriendo conección a la base de datos.
    
    
    
    '//Cadena SQL para agregar un nuevo cliente en la base de datos
    SQL1 = "INSERT INTO Clientes (        nombres,                  apellidos,                  telefono,                     celular,                 calle,                      numero,                       colonia,                   municipio,               fecha_registro_cliente,    Actividad)" _
                       & "VALUES ('" & Form2.txtNombre & "','" & Form2.txtApellidos & "','" & Form2.txtTelefono & "','" & Form2.txtCelular & "','" & Form2.txtCalle & "','" & Form2.txtNumerodcasa & "','" & Form2.txtColonia & "','" & Form2.txtMunicipio & "', '" & Form2.MonthView1.Value & "', 'Nuevo' )"

    CNN.BeginTrans  '<{----{ Iniciando una transaccion
    RST.Open SQL1, CNN, adOpenStatic    '<---[ Se abre el recorset1 (INSERT)
    RST.Close   '<---[ Se cierra el recorset1
    CNN.CommitTrans '<{----{ Cerrando una transaccion exitosa.
    CNN.Close       '<{----{ Cerrando coneccion a la base de datos.
End Sub
Como ves aqui arriba yo solo utilizo CNN.BeginTrans y CNN.CommitTrans que es un todo o nada sin escalas.

Pero ahora digamos que queremos un boleto y hay posibilidades de cancelar la compra, pero antes debemos de apartar el producto, en este caso, el boleto que representa un determinado numero de asiento.

bueno pues muy facil:


Código:
SQL1 = " ( cadena sql para comprar un boleto en donde el numero de asiento = al que quiere el cliente)"
    CNN.BeginTrans  '<{----{ Iniciando una transaccion
    RST.Open SQL1, CNN, adOpenStatic    '<---[ Se abre el recorset1 (INSERT)

if msgbox ("Desea comprar?", vbyesno,"comprar") = vbyes then

    RST.Close   '<---[ Se cierra el recorset1
    CNN.CommitTrans '<{----{ Cerrando una transaccion exitosa.
    CNN.Close       '<{----{ Cerrando coneccion a la base de datos.
else 
    RST.Close   '<---[ Se cierra el recorset1
    cnn.RollbackTrans '<{----{ deshace los cambios
    CNN.Close       '<{----{ Cerrando coneccion a la base de datos.
end if
en este caso no es necesario que cierres la transaccion en el mismo procedimiento, podrias poner el cierre de la transaccion en otro procedimiento pero antes ya quedo apartado y al momento de cerrar por ejemplo en este caso yo mandaria llamar a un procedimiento digamos:

Código:
Call ConcretarCompra ( "si/no")

....

sub ConcretarCompra ( yesno as string)
if yesno = "si" then

    RST.Close   '<---[ Se cierra el recorset1
    CNN.CommitTrans '<{----{ Cerrando una transaccion exitosa.
    CNN.Close       '<{----{ Cerrando coneccion a la base de datos.
else 
    RST.Close   '<---[ Se cierra el recorset1
    cnn.RollbackTrans '<{----{ deshace los cambios
    CNN.Close       '<{----{ Cerrando coneccion a la base de datos.
end if
end sub
anque segun MS no es recomendable es posible siempre y cuando seas responsable de terminarla con committrans o con rolbacktrans, que en el idioma humano seria: autorizar el movimiento para committrans y cancelar el movimiento para rolbacktrans.

http://www.forosdelweb.com/f69/workspace-886036/
  #16 (permalink)  
Antiguo 20/03/2011, 15:54
 
Fecha de Ingreso: agosto-2007
Mensajes: 66
Antigüedad: 17 años, 2 meses
Puntos: 0
Respuesta: bloquear tabla y registros

Muy bueno Gakex esto de las transiciones, de hecho ya estoy modificando el sistema en que estoy trabajando para ponerlo en practica. Pero tomando en cuenta que la tenes mas clara que yo insisto en la consulta de bloquear el registro, ya que esto de la transicion ejecuta todos los procesos pendientes o los retrotrae, pero que pasaria si en el momento de confirmar la transacion el otro usuario confirma tambien la transicion con los mismos datos que yo. Necesito que hasta que yo no termine con mis procesos el otro usuario no pueda tomar el registro
  #17 (permalink)  
Antiguo 20/03/2011, 16:33
Avatar de Gakex  
Fecha de Ingreso: enero-2009
Mensajes: 137
Antigüedad: 15 años, 10 meses
Puntos: 4
Respuesta: bloquear tabla y registros

http://es.wikipedia.org/wiki/Transac...(base_de_datos)
http://www.monografias.com/trabajos1....shtml#sentenc

Eso creo que es improbable ya que las transacciones no permiten que el usuario utilice un registro que esta en medio de una transacción.
pero para que es tu base de datos?
cuales son los eventos que quieres evitar segun tu sistema?
  #18 (permalink)  
Antiguo 20/03/2011, 18:24
 
Fecha de Ingreso: agosto-2007
Mensajes: 66
Antigüedad: 17 años, 2 meses
Puntos: 0
Respuesta: bloquear tabla y registros

Cita:
Iniciado por Gakex Ver Mensaje
http://es.wikipedia.org/wiki/Transac...(base_de_datos)
http://www.monografias.com/trabajos1....shtml#sentenc

Eso creo que es improbable ya que las transacciones no permiten que el usuario utilice un registro que esta en medio de una transacción.
pero para que es tu base de datos?
cuales son los eventos que quieres evitar segun tu sistema?
El tema no es permitir o no editar un registro que esta en medio de una transacion, quiero que ni siquiera lo pueda leer, de manera que cuando va a leer un registro que esta en transacion me genere un error, yo lo intercepto y pongo alguna leyenda como "operacion en curso" hasta que termine la transacion.
Mi sistema es un sistema contable, multiusuario, bastante complicado que realiza procesos de actualizacion en varias tablas a la vez, por lo que tengo que controlar y evitar que varios usuarios puedan trabajar y leer a la vez un mismo registro en el momento que se genera una transacion
Por lo que pude ver y testear inicie una transacion y puse un stop justo antes de CommitTrans, por otro lado trate de leer el registro que iva a ser actualizado en la transicion anterior y me lo permitio leer sin ningun problema, ovbiamente me trajo el dato anterior por lo que si continuase con los procesos me generaria varios errores que los evitaria si en primera instancia evito la lectura del registro que quiero bloquear

Última edición por g_cury; 20/03/2011 a las 18:34

Etiquetas: bloquear, registros, tablas
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 03:47.