Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Firebird e Interbase
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 18-11-2010
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 26
guillotmarc Va por buen camino
Hola.

Parece bastante lógico pensar que tus problemas vienen por transacciones demasiado largas (en tiempo y nº de registros).

Las transacciones tienen que ser lo más cortas posibles, y sobre todo nunca debes dejar transacciones abiertas con modificaciones realizadas (esos registros quedan bloqueados, con lo que bloquean las importaciones, los procedimientos almacenados, etc. ...). Yo incluso te recomendaría no dejar nunca transacciones abiertas de ningún tipo (ni siquiera que sean de lectura).

Así pues, en tu proceso de importación de datos, ve confirmando las transacciones cada poco rato (por ejplo. cada 500 registros es un buen valor), en lugar de esperar hasta el final de la importación.

Y en tu aplicación, no dejes nunca transacciones abiertas. Si el usuario tiene que modificar datos, ponlos en un ClientDataset, de manera que el usuario puede modificar los datos tan tranquilamente como quiera (ya que no se mantiene ninguna transacción abierta), y cuando sea necesario los aplicas a la base de datos llamando al método ApplyUpdates (eso inicia una transacción, ejecuta las sentencias INSERT, DELETE y UPDATE necesarias para aplicar a la Base de Datos los cambios realizados a los Datos en el ClientDataset, y cierra automáticamente la transacción. Todo el proceso apenas dura unos pocos milisegundos con la transacción abierta).

En definitiva, cuanto más cortas sean tus transacciones, menos posibilidades hay de encontrar bloqueos. Y si las transacciones solo duran unos pocos milisegundos (abres la transacción, lees los datos, se pasan al clientdataset y se cierra, o se realizan los cambios y se cierra) es bastante difícil encontrar bloqueos (yo puedo contar con los dedos de una mano los bloqueos que me he encontrado en diez años usando Firebird).

Respecto al tamaño de la base de datos, yo no me preocuparía lo más mínimo por ello. Firebird es una base de datos multigeneracional, cuando modificas un registro se hace una copia del mismo, eso quiere decir que si hay muchas modificaciones simultaneas en largas transacciones abiertas (como parece ser actualmente tu caso), entonces tienes muchas copias de tus registros. Pero una vez confirmada la transacción, ese espacio se reutiliza. Así que tu Base de Datos crecerá hasta un tamaño determinado para poder mantener todas las versiones en memoria que haces en tu uso normal del programa, y a partir de ese punto solo crecerá moderadamente, a medida que se vayan dando de alta registros.

NOTA: Aunque verás que si haces las transacciones más cortas, tu base de datos también crece mucho menos (ya que no tiene que mantener tantas versiones simultaneas de los registros).

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).

Última edición por guillotmarc fecha: 18-11-2010 a las 19:45:58.
Responder Con Cita
  #2  
Antiguo 18-11-2010
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 26
guillotmarc Va por buen camino
NOTA: Por cierto, para cambiar el tamaño de la base de datos yo hago un Backup y un Restore (parámetro -P). No creo que puedas hacerlo con el GFix.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #3  
Antiguo 18-11-2010
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 26
guillotmarc Va por buen camino
Casimiro, ¿ puedes borrar este último mensaje ?, te me has adelantado.



Gracias.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #4  
Antiguo 18-11-2010
Avatar de Casimiro Noteví
Casimiro Noteví Casimiro Noteví is offline
Merodeador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.676
Poder: 10
Casimiro Noteví Tiene un aura espectacularCasimiro Noteví Tiene un aura espectacular
Cita:
Empezado por guillotmarc Ver Mensaje
Casimiro, ¿ puedes borrar este último mensaje ?, te me has adelantado.

Gracias.
Así queda repetido, para machacar mejor las ideas y no olvidarlas
Responder Con Cita
  #5  
Antiguo 18-11-2010
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.806
Poder: 22
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Para el tema de insertar y cerrar transacciones mira este link
Básicamente debes hacer esto
Código Delphi [-]
 with Consulta do
  begin
    SQL.Clear;
    SQL.Add( 'INSERT INTO CLIENTES' );
    SQL.Add( '( NOMBRE, NIF, IMPORTEPTE )' );
    SQL.Add( 'VALUES' );
    SQL.Add( '( ''ANTONIO GARCIA LOPEZ'', ''46876283D'', 140.23 )' );

    Transaction.StartTransaction;

    try
      ExecQuery;
      Transaction.Commit;
    except
      on E: Exception do
      begin
        Application.MessageBox( PChar( E.Message ), 'Error de SQL', MB_ICONSTOP );
        Transaccion.Rollback;
      end;
    end;
  end;

y mejor si lo haces así

Código Delphi [-]
var
  i: Integer;
  dwTiempo: DWord;
begin
  with Consulta do
  begin
    //////////////  METODO RÁPIDO  ////////////////

    dwTiempo := TimeGetTime;

    Transaction.StartTransaction;

    SQL.Clear;
    SQL.Add( 'UPDATE CLIENTES' );
    SQL.Add( 'SET NOMBRE = :NOMBRE' );
    SQL.Add( 'WHERE ID = :ID' );
    Prepare;

    for i := 1 to 1000 do
    begin
      Params.ByName( 'NOMBRE' ).AsString := 'NOMBRE CLIENTE Nº '+ IntToStr( i );
      Params.ByName( 'ID' ).AsInteger := i;
      ExecQuery;
    end;

    try
      Transaction.Commit;
    except
      on E: Exception do
      begin
        Application.MessageBox( PChar( E.Message ), 'Error de SQL', MB_ICONSTOP );
        Transaccion.Rollback;
      end;
    end;

    ShowMessage( 'Tiempo: ' + IntToStr( TimeGetTime - dwTiempo ) + ' milisegundos' );
  end;
end;

Última edición por duilioisola fecha: 18-11-2010 a las 20:43:54.
Responder Con Cita
  #6  
Antiguo 18-11-2010
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 26
guillotmarc Va por buen camino
Duilioisola te recomiendo que cambies las excepciones de captura de error por esta :

Código Delphi [-]
  except       
    on E: Exception do 
    begin
      Transaccion.Rollback;  // Primero cancelamos la transacción
      Application.MessageBox( PChar( E.Message ), 'Error de SQL', MB_ICONSTOP );
    end;
  end;

Puesto que estás dejando abierta la transacción (y los registros bloqueados) hasta que el usuario acepta el mensaje de error. Y no hay ninguna necesidad de ello (imagínate que el usuario mantiene el mensaje en pantalla, para poder llamar al servicio técnico. Igual te deja media hora con los registros bloqueados).

Siempre se debería evitar que las transacciones (especialmente las que ya han modificado algo) permanezcan abiertas a la espera de una acción del usuario.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).

Última edición por guillotmarc fecha: 18-11-2010 a las 21:03:30.
Responder Con Cita
  #7  
Antiguo 19-11-2010
Toni Toni is offline
Miembro
 
Registrado: may 2003
Ubicación: Barcelona - España
Posts: 364
Poder: 24
Toni Va por buen camino
Hola,

En mis programas suelo utilizar los componentes IBX + datasetprovider + clientdataset. Y abro las consultas en clientdataset y realizo las actualizaciones mediante el ApplyUpdate(). Esto es lo que suelo utilizar para las consultas y las consultas actualizables.

En el programa de importacion que comentaba lo que si es cierto que realizo un commit por cada nuevo registro que añado o modifico, esto lo realizo por que en caso de error en un registro no quiero que afecta a otros posibles registros. Y me deje de importar un bloque de xxx registros. Tambien decir que en este programa de importacion estoy utilizando Ibquery + IbupdateSQL y en otros casos utilizo ibx + dsp + clientdataset. Unos procesos de importacion usan un modelo de datos y otros el otro.

Por cierto, para las consultas de modificacion, insercion y/o procedimientos alm. como los utilizais con los clientdataset para sincronizar todo en una transaccion?

Muchas gracias a todos.

Saludos,
__________________
Saludos,

Bitman
Responder Con Cita
  #8  
Antiguo 19-11-2010
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.806
Poder: 22
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Muy buen apunte guillomarc.
Habrá que dejarle un mensajito en le blog de Delphi al Limite que es de dónde saqué el código.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
rendimiento de PHP Ñuño Martínez PHP 1 20-09-2006 06:29:55
Problema grave de rendimiento ACK Firebird e Interbase 13 12-09-2005 17:10:44
¿ Cúal es el Rendimiento ? sierraja Firebird e Interbase 7 12-09-2005 15:37:44
Rendimiento TStringList Delphius Varios 7 13-06-2005 07:16:46
rendimiento carlomagno Firebird e Interbase 14 06-07-2004 17:05:13


La franja horaria es GMT +2. Ahora son las 13:43:09.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi