En este artículo ya habíamos visto un método para evitar que los usuarios se conecten más de una vez a la Base de Datos:

Evitando que un usuario se conecte más de una vez a la Base de Datos

pero allí podríamos tener un pequeño problema si la computadora donde se encuentra el Servidor del Firebird se apaga incorrectamente, dejando por lo tanto nombres de usuarios en la tabla CONECTADOS. Esos usuarios evidentemente cuando se reinicia el Servidor no estarán conectados pero en la tabla CONECTADOS dirá que sí lo están. Una solución sería que un usuario quien no estaba conectado borre todas las filas de esos usuarios en la tabla CONECTADOS. Funcionará bien, pero, hmmmmmmm, no es profesional, ¿verdad?

Aquí hay otro método para borrar a esos usuarios “fantasmas”. Son “fantasmas” porque la tabla CONECTADOS nos indica que están conectados a la Base de Datos pero la realidad es que no lo están.

Lo que haremos será agregarle una columna a la tabla CONECTADOS y en esa columna guardaremos el identificador de la conexión. Luego, en nuestro trigger antes de intentar la inserción borraremos a todos los usuarios cuyos identificadores de conexión no se encuentren en la tabla CONECTADOS y también en la tabla MON$ATTACHMENTS.

En la tabla del sistema MON$ATTACHMENTS se guardan los datos de todas y cada una de las conexiones actuales. Uno de esos datos es el identificador de la conexión.

Entonces, la estructura de nuestra tabla CONECTADOS ahora sería la siguiente:

CONECTADOS1

Captura 1. Si haces clic en la imagen la verás más grande

Como puedes ver en la Captura 1. a la tabla CONECTADOS se le agregó la columna CON_IDECON, para guardar en esa columna el identificador de la conexión (ese identificador lo encontraremos en la tabla MON$ATTACHMENTS y para la conexión actual siempre será igual a CURRENT_CONNECTION).

El trigger para insertar un usuario a la tabla CONECTADOS

Nuestro trigger ahora cambiará un poco, quedará así:

Listado 1.

CREATE TRIGGER INSERTAR_CONECTADO
   ACTIVE ON CONNECT
   POSITION 2
AS
BEGIN

   -- Primero, se borran las filas de los usuarios que no están conectados
   -- pero aparecen como conectados

   DELETE FROM
      CONECTADOS
   WHERE
      CON_IDECON NOT IN (SELECT MON$ATTACHMENT_ID FROM MON$ATTACHMENTS);

   -- Segundo, se trata de insertar una fila a la tabla CONECTADOS.
   -- Como la tabla CONECTADOS tiene una restricción UNIQUE KEY, un usuario
   -- no se podrá conectar más de una vez al mismo tiempo

   INSERT INTO CONECTADOS
              (CON_IDENTI, CON_IDECON , CON_NOMBRE , CON_TIMEST)
       VALUES (0 , CURRENT_CONNECTION, CURRENT_USER, CURRENT_TIMESTAMP);

END;

¿Qué hace este trigger?

Primero, borrará todas las filas de la tabla CONECTADOS cuyo valor de CON_IDECON no coincida con algún valor de ATTACHMENT_ID de la tabla ATTACHMENTS. En otras palabras, en la tabla CONECTADOS quedarán solamente los nombres de los usuarios que efectivamente están conectados a la Base de Datos, no tendrá filas “fantasmas”.

Segundo, intentará insertar una fila a la tabla CONECTADOS. Si el nombre del usuario que intenta la conexión no existe en esa tabla entonces podrá continuar pero si existe entonces ocurrirá una excepción y se evitará la conexión.

El trigger para borrar un usuario de la tabla CONECTADOS

Este trigger quedará exactamente igual al que habíamos visto en el artículo anterior, no tiene por qué cambiar.

Listado 2.

CREATE TRIGGER BORRAR_CONECTADO
   ACTIVE ON DISCONNECT
   POSITION 3
AS
BEGIN

   DELETE FROM
      CONECTADOS
   WHERE
      CON_NOMBRE = CURRENT_USER;

END;

Conclusión:

Para evitar que un apagado anormal del Servidor del Firebird deje usuarios “fantasmas” en la tabla CONECTADOS podemos tener en esa tabla una columna que nos indique cual es el identificador de cada conexión. Así, antes de intentar insertar los datos de un usuario en la tabla CONECTADOS borramos las filas de esa tabla que no tengan una conexión activa. Lo que conseguiremos será que la tabla CONECTADOS siempre nos muestre los nombres de los usuarios que efectivamente se encuentran conectados.

Artículos relacionados:

Limitando la cantidad de usuarios conectados

Evitando que un usuario se conecte más de una vez a la Base de Datos

El índice del blog Firebird21

El foro del blog Firebird21

Anuncios