• Publicidad

Minimizar número de conexiones a base de datos

Aquí encontrarás todo lo que sea específicamente acerca de módulos de Perl. Ya sea que estás compartiendo tu módulo, un manual o simplemente tienes una duda acerca de alguno.

Minimizar número de conexiones a base de datos

Notapor Lor » 2012-03-01 10:46 @490

Tengo una aplicacion que utiliza sesiones con el módulo Apache::Session::Informix. Mi objetivo es minimizar el número de conexiones a la base de datos, llevarla de dos a una sola.

Estoy abriendo una conexión primeramente para acceder a los datos propios objeto de la aplicación, pero por lo que veo al usar sesiones y analizar un poco el módulo Apache::Session::Informix, veo que se abre una segunda para conectarse a la base de manejo de sesiones. Mi pregunta es :

1) - Si abro una primera conexión en la aplicación obteniendo un $dbh, ¿podría adaptar el módulo Apache::Session::Informix para que reciba este $dbh y no tenga que abrir una conexión nueva?

2)- ¿Cómo podría hacerlo?

3)- O por el contrario no abrir una conexión en la aplicación, pero utilizar la conexión abierta en el módulo Apache::Session, pero para este caso debería estar enviando esta $dbh obtenida a la aplicación para ser utilizada.

¿Es esto posible? Espero haya sabido expresarme. Muchas gracias.
Lor
Perlero nuevo
Perlero nuevo
 
Mensajes: 187
Registrado: 2005-04-28 05:47 @282

Publicidad

Re: Minimizar número de conexiones a base de datos

Notapor explorer » 2012-03-01 14:57 @665

Creo que no te haca falta modificar nada del código del módulo.

En la propia sinopsis del módulo, hay un ejemplo de cómo se puede realizar el enlazado con el hash de sesión, en el caso de que la base de datos ya esté abierta:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  #or, if your handles are already opened:
  2.  
  3.  tie %hash, 'Apache::Session::Informix', $id, {
  4.     Handle => $dbh,
  5.     Commit => 1
  6.  };
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Le tienes que pasar $dbh, que es el gestor de la conexión a la base de datos, con lo que lo único que tienes que hacer es haberla abierto antes. De esa manera, Apache::Session::Store::Informix no abre una nueva conexión:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. sub connection {
  2.     my $self    = shift;
  3.     my $session = shift;
  4.    
  5.     return if (defined $self->{dbh});
  6.  
  7.     if (exists $session->{args}->{Handle}) {
  8.         $self->{dbh} = $session->{args}->{Handle};
  9.         $self->{commit} = $session->{args}->{Commit};
  10.         return;
  11.     }
  12.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Es más: si te fijas en este trozo de código, verás que hay un return que hace terminar connection() en el caso de que estuviera definido $self->{dbh}, así que el propio módulo ya tiene incorporado el mecanismo necesario para no tener que hacer más de una conexión, así que no sé qué código tienes hecho para que digas que se conecta dos veces :wink:
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Minimizar número de conexiones a base de datos

Notapor Lor » 2012-03-08 09:46 @448

¡¡Gracias!! Hace una semana que continúo trabajando en el mismo tema y persisten los errores. El caso, es que tengo que trabajar con dos bases de datos Informix diferentes: una base con tablas de datos a los que quiero acceder llamémosla 'baseXXX' y la otra la base 'Sessions' utilizada para el manejo de sesiones según el módulo Apache::Session:Informix.

He tratado de utilizar tu sugerencia pero me tira el siguiente error:
DBD::Informix::st execute failed: SQL: -255: Not in transaction. at /usr/local/share/perl/5.8.8/Apache/Session/Store/Informix.pm line 76., referer: http://www......../intranet.htm
[Thu Mar 08 11:01:08 2012] [error] [client 172.16.253.13] commit ineffective with AutoCommit enabled at /usr/local/share/perl/5.8.8/Apache/Session/Store/Informix.pm line 93., referer: http://www....../intranet.htm



Ambas bases de datos se encuentran en modo transaccional : U (unbuffered)

El código que estoy utilizando es:

Sintáxis: [ Descargar ] [ Ocultar ]
  1.  
  2.  
  3. ## * * * Aplicación 1  
  4.  
  5. # Abro una conexión a la base sessions 
  6. my $base = 'sessions'; 
  7. my $dbh = DBI->connect("dbi:Informix:$base" , '', '', 
  8.               { 'PrintError'=>1, 
  9.               'RaiseError'=>1})or die "Could not connect, stopped\n"; 
  10.  
  11. ........ 
  12. # Creo una sesión usando el gestor obtenido 
  13. my %session; 
  14. eval { 
  15.       tie %session, 'Apache::Session::Informix', $sid, { 
  16.           Handle => $dbh , 
  17.           Commit   => 1, 
  18.           LongReadLen=> 8*2**10} or die "No puede crear la sesion $sid"; 
  19.  }; 
  20.  
  21.  if ($@) { 
  22. print ‘ Hubo error en la creación’; 
  23. else { 
  24. # se creo la sesión correctamente guardo valores: 
  25. $session{id} = $id_login ; 
  26. $session{nombre} = ‘Juan Perez’;  # Guardo en sesión un valor  
  27.  
  28.  
  29.  
  30. ##  * * Luego en otra aplicación  
  31.  
  32. # Verifico si existe la sesión creada, si existe extraigo los valores $session{id} y $session{nombre} 
  33.  
  34. # Veo que la sesión no existe. No se almacenaron los datos de la sesión en la base Sessions.sessions 
  35.  



¡¡¡Muchas gracias!!!
Lor
Perlero nuevo
Perlero nuevo
 
Mensajes: 187
Registrado: 2005-04-28 05:47 @282

Re: Minimizar número de conexiones a base de datos

Notapor explorer » 2012-03-08 12:11 @549

Según este mensaje, el problema con DBD::Informix para que saque ese error, es que el programador tenía puesta la opción AutoCommit => 1, pero viendo el código de Apache::Session::Store::Informix, vemos que, efectivamente, lo ponen a 0, pero SOLO si es el módulo el que se encarga de hacer la conexión. Si le pasas tu el $dbh, entonces tu eres el responsable de apagar el AutoCommit.

Mira las líneas que usa el módulo para abrir la conexión a la base de datos:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     $self->{dbh} = DBI->connect(
  2.         $datasource,
  3.         $username,
  4.         $password,
  5.         { RaiseError => 1, AutoCommit => 0 }
  6.     ) || die $DBI::errstr;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Haz tu lo mismo: coloca un AutoCommit => 0 en tu código.

A propósito... divertido leer la página de manual de DBD::Informix, en las zonas que habla de AutoCommit... (just one more reason to hate AutoCommit) :lol:
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Minimizar número de conexiones a base de datos

Notapor Lor » 2012-03-08 12:45 @573

¡¡¡ GRACIAS !!! Apenas llegue a mi trabajo lo pruebo.

He probado tantas cosas que creo que ya hice el intento con esta alternativa. ¿Podría suceder que no hiciese el commit ? Me sucedió que si bien creaba la sesión y almacenaba valores, sin problemas, luego al consultarlos no existían.


¡¡¡Muchas gracias por tu esfuerzo y tiempo!!!
Lor
Perlero nuevo
Perlero nuevo
 
Mensajes: 187
Registrado: 2005-04-28 05:47 @282

Re: Minimizar número de conexiones a base de datos

Notapor explorer » 2012-03-08 14:01 @626

Precisamente, el manual dice que siempre hay que indicar la opción Commit => 1 en caso de usar una Informix.

Mirando el código del módulo, verás que sí que hace el commit() de forma automática.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Minimizar número de conexiones a base de datos

Notapor Lor » 2012-03-09 06:38 @318

Vamos avanzando de a poco, la sesión se crea correctamente y puedo almacenar variables también sin errores.
Ahora el problema está cuando una vez ya en sesión quiero acceder a los valores almacenados en la misma.

Hago lo siguiente:
Sintáxis: [ Descargar ] [ Ocultar ]
  1. my %session;   
  2.     eval { 
  3.     tie %session, 'Apache::Session::Informix', $sid, { 
  4.           Handle => $dbh, 
  5.           Commit => 1 } or die "No puede localizar la session $sid"; 
  6.    }; 
  7.         my $nombre= $session{'nombre'}; 
  8.         my $apellido= $session{'apellido'}; 
  9.         my $id_login= $session{'id_login'}; 
  10.  
  11.  if ($@) {  # Verifico si se produjo algun error 
  12.  
  13.    print... $@   ......"; 
  14.      
  15.  


Los valores recuperados están vacíos, no los puedo recuperar: $nombre, $apellido, $id_login


$@ indica:

DBD::Informix::st fetchrow_arrayref failed: SQL: -1820: Host variable type has been changed between fetches or puts. at /usr/local/share/perl/5.8.8/Apache/Session/Store/Informix.pm line 78


¡¡¡Gracias!!!
Lor
Perlero nuevo
Perlero nuevo
 
Mensajes: 187
Registrado: 2005-04-28 05:47 @282

Re: Minimizar número de conexiones a base de datos

Notapor Lor » 2012-03-09 09:17 @428

¡¡¡¡Listo salio!!!! ¡¡¡Creo que sí!!! El último error estaba asociado a que realizaba el mismo proceso dos veces, una en la aplicación y otra, en una función que era llamada ubicada en un paquete.

Sintáxis: [ Descargar ] [ Ocultar ]
  1. my %session; 
  2.   eval { 
  3.     tie %session, 'Apache::Session::Informix', $sid, { 
  4.           Handle => $dbh, 
  5.           Commit => 1 } or die "No puede localizar la session $sid"; 
  6.    }; 


Ahora lo hago una sola vez y envío por referencia donde lo necesite a \%session.

explorer: ¡¡¡¡¡¡Gracias por todo!!!!!!
Lor
Perlero nuevo
Perlero nuevo
 
Mensajes: 187
Registrado: 2005-04-28 05:47 @282

Re: Minimizar número de conexiones a base de datos

Notapor Lor » 2012-03-12 10:51 @494

Continúo con problemas. No se graban los valores almacenados en la sesión.
Error:DBD::Informix::st fetchrow_arrayref failed: SQL: -1820: Host variable type has been changed between fetches or puts. at /usr/local/share/perl/5.8.8/Apache/Session/Store/Informix.pm line 78

Sintáxis: [ Descargar ] [ Ocultar ]
  1. # Aplicación 
  2. #------------------------------------------------------------------------------- 
  3.  
  4. # Recibo parámetro POST el id de la sesión. 
  5.  
  6. import_names('Q'); 
  7. my $id = $Q::id_session || ""; 
  8.  
  9.  
  10. # Abro una conexión a la base sessions 
  11. my $base = 'sessions'; 
  12. my $dbh = datacon_base($base); 
  13.  
  14.  
  15.  
  16. my ($sesion_valida) = autenticar_sesion( $dbh, $id); 
  17.  
  18. if ($sesion_valida eq 'F') { 
  19.         print "Hubo error………."; 
  20.   } 
  21. else { 
  22.  
  23.     # Sesión Válida, Recupero Variables almacenados en sesión previamente 
  24.     #--------------------------------------------------------------------- 
  25.  
  26. my %session; 
  27.      eval { 
  28.          tie %session, 'Apache::Session::Informix', $sid, { 
  29.                   Handle => $dbh , 
  30.                   Commit => 1 } or die "No puede crear la sesión $sid"; 
  31.      }; 
  32.   
  33.  
  34.     # print “  Imprimo error si hubo $@ ........................."; 
  35.     #  
  36.     # ERROR producido:  DBD::Informix::st fetchrow_arrayref failed: SQL: -1820: 
  37.     # Host variable type has been changed between fetches or  
  38.     # puts. at /usr/local/share/perl/5.8.8/Apache/Session/Store/Informix.pm line 78 
  39.  
  40.  
  41.     #  Obtengo valores guardados 
  42.     my $nombre= $session->{'nombre'}; 
  43.     my $apellido= $->{'apellido'}; 
  44.  
  45.     print “ Imprimo $snombre y $apellido ” ; 
  46.  
  47.     # $nombre y $apellido están vacíos...  Se guardaron bien sin errores, pero es como que no se hizo el commit(); 
  48.          
  49.  
  50. ... 
  51.  
  52.  
  53. # Funciones 
  54. #-------------------------------------------------------------------------------- 
  55.  
  56. # Abro una conexión a base sessions 
  57. #------------------------------------------------------------------------------- 
  58. my $base = 'sessions'; 
  59. my $dbh = funciones_rgenuinos::datacon_base($base); 
  60.  
  61.  
  62. # Creo una sesión 
  63. #--------------------------------------------------------------------------------------------------------------- 
  64. sub crear_sesion { 
  65.  
  66.  my $dbh= shift; 
  67.  my $nombre= shift; 
  68.  
  69.  my $id = undef; 
  70.  
  71.  my %session; 
  72.   eval { 
  73.       tie %session, 'Apache::Session::Informix', $id, { 
  74.           Handle => $dbh , 
  75.           Commit   => 1} or die "No puede crear la sesión $id"; 
  76.    }; 
  77.  
  78.   if ($@) { 
  79.          $sid= 'F';  # Hubo error no se creo la sesión 
  80.   } 
  81.  else { 
  82.  
  83.     # La sesión fue creada, guardo valores a la sesión 
  84.     #-------------------------------------------------------------------------- 
  85.  
  86.      $session{'nombre'} = ‘Juan’;   # Sesión creada guardo variable nombre 
  87.      $session{'apellido'} =  ‘Perez’;    
  88.  
  89.      $id = $session{_session_id}; # id de la sesión generado 
  90.  
  91. return ($id); 
  92.  
  93.  
  94.  
  95. #----------------------------------------------------------------------------------- 
  96. # Función verifica si existe la sesión $sid, si existe extrae valores guardados previamente 
  97. #-------------------------------------------------------------------------------------- 
  98.  
  99. sub autenticar_sesion { 
  100.  
  101. my $dbh= shift; 
  102. my $id = shift; 
  103.  
  104. my %session; 
  105.  
  106.  eval { 
  107.    tie %session, 'Apache::Session::Informix', $id, { 
  108.           Handle => $dbh , 
  109.           Commit => 1 } or die "No puede crear la sesión $id"; 
  110.   }; 
  111.  
  112.     if ($@) { 
  113.         # Hubo algún tipo de error 
  114.         $sesion_valida='F'; 
  115.     } 
  116.     else { 
  117.         # La sesion existe, es valida, Actualizo hora de expiración 
  118.          
  119.         $session{'hora_ejecucion'} = $hora_actual;  # Guardo valor en sesión 
  120.         $sesion_valida ='T'; 
  121.  
  122.  
  123. return ($sesion_valida); # devuelvo ‘T’ o ‘F’ indicando si existe sesión válida. 
  124.  
  125.  
  126.  



¿Qué es lo que veo? Guarda bien los datos en la sesión, pero cuando quiero recuperar los datos guardados están vacíos.

Bueno, ¡¡¡cualquier ayuda me sería muy valiosa!!! Gracias
Lor
Perlero nuevo
Perlero nuevo
 
Mensajes: 187
Registrado: 2005-04-28 05:47 @282

Re: Minimizar número de conexiones a base de datos

Notapor explorer » 2012-03-12 11:11 @507

El error de Informix deberás buscarlo en la documentación correspondiente.

Lo que veo es que las líneas 42 y 43 deberían ser
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     my $nombre   = $session{'nombre'};
  2.     my $apellido = $session{'apellido'};
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Y... las comillas que muestras, no creo que sean del todo válidas, para Perl. Me refiero a que no es lo mismo usar "...", que “...” (comillas tipográficas). Lo mismo para las comillas simples.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Módulos

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 2 invitados