Estoy haciendo una aplicación cliente servidor. En mi pc tengo montados el Apache y Postgresql

Tengo un problema que no puedo resolver. Te explico estoy haciendo una aplicación cliente-servidor. En la maquina servidor tengo montado el apache y postgresql. Mi problemas es que cuando un cliente con permiso de escritura abre un registro de mi base de datos tengo que impedir que otro usuario abra el mismo registro y no pueda abrirlo hasta que no lo cierre el primero. Esto lo he resuelto poniendo un campo más en mi tabla llamado uso lo pongo a true cuando hay alguien leyendo el registro y así no dejo que entre ningún usuario hasta que no se ponga a false. Mi problema es que si se va la luz o si se usa el navegador netscape(no controla el evento de cierre de ventana) no puedo poner ese campo a false y nadie podría entrar nunca a ese registro. Podrías darme alguna solución a este problema. Estoy trabajando en java, jsp, html, javascript.

8 respuestas

Respuesta
1
Bloqueo de registros en Webs:
Usa timeouts: Es inexacto, pero te garantiza que no te quedará nunca un registro bloqueado. Cada vez que un usuario abre la página del registro, en el servidor se pone a cero un contador (el timeout). Mientras dicho contador no supere una cifra límite (el parámetro timeout, que suele ser de unos 5 minutos = 300 segundos) se considera que el usuario sigue consultando el registro.
En tu caso, lo mejor es que en el campo "uso" coloques un campo "datetime" con la fecha y hora exacta en que el usuario abre el registro.
Cuando en general un usuario intente abrir cualquier registro, siempre tendrá que comprobar primero que la fecha-hora actual menos la fecha-hora que indica el correspondiente campo "uso" supera el valor del timeout, o sea, 5 minutos. Si no lo supera, significa que el registro está siendo leído por otro usuario.
En caso de que un usuario tarde más de 5 minutos en leer la web del registro, te interesa que el registro se mantenga bloqueado más tiempo. Esto se consigue con una opción HTML o JavaScript que cada 5 minutos invoque en un frame invisible una llamada a un script que simplemente actualiza la fecha-hora del campo "uso" del registro que se está consultando.
Respuesta
1
Lo mejor que puedes hacer en este caso es meter en un método de una clase el acceso y modificación de los datos de esa tabla. Ese método lo haces syncronized así:
public synchronized void updateCampo(String valor){...}
Con esto te aseguras que nunca va a haber más de 1 thread accediendo a la vez a tu método, con lo que si 2 personas entran a la vez la primera que coja los recursos de ejecución ejecutara primero el método quedando la 2ª a la espera. Con esto incluso te puedes evitar el campo en la BBDD.
Respuesta
1
Siento no poder ayudarte, lo que me comentas se escapa a mis conocimientos. Lo mejor será que contactes con alguno de los expertos en Bases de Datos.
Respuesta
1
Me parece que no te voy a poder solucionar del todo tu problema ya que trabajas con herramientas que no utilizo.
Si fuera una base de datos de Access, yo establecería una serie de ordenes que actualizaran ese campo a false, en el evento open de un formulario de inicio ( Herramientas->Inicio...->Mostrar Formulario/página) que una vez las hubiera ejecutado se cerrara automáticamente.
Otra cosa que podrías hacer es mirar los permisos que puedes establecer durante la apertura de tablas, como tiene Access para el bloqueo de modificaciones.
Con estos parámetros podremos controlar el modo de apertura y como se ha de actuar ante las modificaciones de otros usuarios.
Por ejemplo:
- Tipo de apertura
BSeeChanges - Genera un error en tiempo de ejecución que nos avisa si otro usuario esta realizando modificaciones en el registro -
- Modo de bloqueo
DbPessimistic - bloquea la página de registros con la que se trabaja mientras se están editando los datos -
Lo siento mucho friend.
Hasta luego, query.
Respuesta
1
Y grracias por preguntar...
No conozco mucho java ni javascript, pero calculo que si el servidor de la base es un derivado de SQL, en la apertura de la tabla deberías tener la posibilidad de indicarle de que manera va a bloquear los registros en caso de edición, por ende no haría falta el campo que usas de testigo.
En una conexión del tipo ODBD en la estructura de la instrucción de apertura de la tabla puedes indicarle, por ej. que sea un bloqueo OPTIMISTA con lo cual bloquea el registro solo en el momento de edición y eso evita que otros usuarios puedan modificarlo más si verlo sin problemas...
¿Puedes copiarme la instrucción que abre la tabla de la base en el servidor?
Respuesta
1
Morente:
Por lo visto has estado viendo condiciones de concurso y te ha dado un poco de ganas de aplicarlo, el bloqueo de relaciones (tablas) tuplas o demás, las hace el DBMS por sí sólo, no hace falta que implementes semáforos y cosas así para poder realizar exclusión mutua entre ambos procesos que compiten por una relación.
Lo que sí, se puede hacer (no sé si específicamente el postgresql) es acotar el bloqueo a las distintas tuplas de una relación, como para no anular la relación entera, ¿entiendes?.
Bueno, epseor haber ayudado. Y lo dicho, no te preocupes tanto por los bloqueos. Por las dudas puedes usar el evento onunload de javascript para realizar el cambio de la bandera cuando cierran el navegador.
Es todo.
..
Respuesta
1
El método que empleas tiene riesgos elevados.
El bloqueo se debe fijar siempre a través de los métodos de apertura de bases de datos...
Se me ocurre declarar (con ASP) el objeto de conexión a la BD con las restricciones del tipo 'session'.
Webs recomendadas: http://www.iec.csic.es/criptonomicon/bd/
http://www.lawebdelprogramador.com/
Respuesta
1
El uso de variables para eso no es bueno, además puede crear conflictos. No he trabajado con postgres, pero podrías probar a forzar a utilizar la opción de abrir en modo exclusivo un registro, de forma que ya te aseguras que otro no vaya a entrar en ese mismo modo para evitar el deadlock. Esto ya lo gestionaría el Gestor de Bases de Datos, es decir, Postgres.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas