Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Conexión con bases de datos
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Conexión con bases de datos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 06-09-2006
Avatar de lucasarts_18
lucasarts_18 lucasarts_18 is offline
Miembro
 
Registrado: mar 2005
Ubicación: Villa Alemana,Chile
Posts: 1.087
Poder: 21
lucasarts_18 Va por buen camino
Controlar Commit y Rollback

Hola compañeros del club:

Estoy realizando mantenciones a un sistema hecho en Delphi 4 y SQL Server 2000, y necesito cambiar algo de caracter importantísimo.

En primer lugar las transacciones están aisladas, ¿que quiero decir con esto?, pues que cada procedimiento almacenado de la base de datos contiene commit y rollback, siendo esto último no un problema para los mantenedores simples, por ejemplos productos, clientes, bodegas, etc...
Mi problema radica es que los modulos de ventas por ejemplo el de factura, al momento de grabar llama a varios SP (Ingresa Factura, Detalle Factura, Cta Corriente del cliente, Actualiza Stock, Etc....) lo cual al momento de producirse un fallo en el segundo u tercero.... SP me deja incosistencias en la BD ya que se produce un commit en cada procedimiento.
Sin lugar a dudas en estos casos lo mejor es controlarlo desde el programa todo lo referente a los commit y rollback, pero aquí yace mi gran duda...
Creo que con el código se entenderá un poco mejor:

Código Delphi [-]
     if combo_vendedor.text ='' then
     begin
        MessageDlg('Ingrese el Código Vendedor', mtWarning, [mbOk],0);
        combo_vendedor.Setfocus;
        exit;
     end;

     if (edt_totalguia.Text ='') then
     begin
        MessageDlg('Debe Calcular el Valor Total de la Factura',mtWarning,[mbOk],0);
        btn_Calculo.SetFocus;
        exit;
     end;

     if Ingresar then
     begin
        Msg :='¿Desea Grabar el Ingreso de la Guía?';
        if MessageDlg(Msg, mtConfirmation,[mbyes, mbNo],0) = mrYes then
        begin
           if (opcion_pago.ItemIndex in [0]) then
           begin
              Msg :='Favor, confirmar la opción de Pago con el CLIENTE'+ #13 + '< CONTADO >'+ #13 +'Si está correcto oprima [Ok], de lo contrario presione [Cancel]';
              if MessageDlg(Msg, mtConfirmation,[mbOK, mbCancel],0) = mrCancel then
              Exit;
           end
           else
           begin
              Msg :='Favor, confirmar la opción de Pago con el CLIENTE '+ #13 + '< CRÉDITO >'+ #13 +'Si está correcto oprima [Ok], de lo contrario presione [Cancel]';
              if MessageDlg(Msg, mtConfirmation,[mbOK, mbCancel],0) = mrCancel then
              Exit;
           end;
           IngresarGuia;
           IngresarCorrelativo;
           lv_i := 1;
           while (lv_i <= grd_Detalle.RowCount -1) do
           begin
              IngresarDetalleGuia;
              ActualizarStockProducto;
              lv_i :=lv_i+1;
           end;
           MessageDlg('Guía de Despacho Ingresada Exitosamente.'+#13+'Ahora Deberá Imprimir.',mtInformation,[mbOk],0);
           btn_buscarguia.Enabled := False;
           btn_Nuevo.Enabled := False;
           btn_Imprimir.Enabled := True;
           btn_Grabar.Enabled := False;
           btn_calculo.Enabled := False;
           btn_Salir.Enabled := False;
           PrecioNormal := 0;
           PrecioOferta := 0;

        end;
     end;
end;

Supongamos IngresarGuia, IngresarCorrelativo son procedimientos delphi que a la vez llaman a procedimientos de SQL Server que contiene commit, mi idea es quitar los commit y en caso de error capturar el código error devuelto por la BD y este asignarlo a una variable pública del formulario para controlar el error, pero no se me ocurre muy bien como implementarlo, según ustedes ¿qué opción me recomendarían ?

Esperando que toda esta parafernalía se entienda

Hasta Luego -
__________________
No todo es como parece ser...
Responder Con Cita
  #2  
Antiguo 06-09-2006
Avatar de kalimero
kalimero kalimero is offline
Miembro
 
Registrado: may 2003
Ubicación: Alicante
Posts: 288
Poder: 21
kalimero Va por buen camino
Código Delphi [-]
try
    if not(conexion.InTransaction) then conexion.BeginTrans;
    ingresarguia;
    ingresarcorrelativo;
    conexion.commit; //todo ha ido bien y confirmamos
except
    //Capturamos la excepcion y hacemos lo que queramos
    //Deshacemos la transaccion
    conexion.Rollback;
end;
Responder Con Cita
  #3  
Antiguo 06-09-2006
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 28
jachguate Va por buen camino
Veo un defecto en el código de kalimero y es que se "traga" la excepción, por lo que aún cuando se ha realizado correctamente el rollback, pueden haber fallos posteriores debido a esto:

yo lo dejaría como:

Código Delphi [-]
Conexion.StartTransaction;
try
  HacerTodoLoQueSeQuiera;
  Conexion.Commit;
except
  Conexion.Rollback;
  raise; //esta línea eleva nuevamente la excepción original después del rollback
end;
Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate

Última edición por jachguate fecha: 06-09-2006 a las 16:00:59.
Responder Con Cita
  #4  
Antiguo 06-09-2006
Avatar de kalimero
kalimero kalimero is offline
Miembro
 
Registrado: may 2003
Ubicación: Alicante
Posts: 288
Poder: 21
kalimero Va por buen camino
Efectivamente Jachguate. No lo he dicho porque doy por supuesto que el interesado ya tenia claro este tema. Me he centrado en el objetivo de la pregunta era saber donde se ponen la llamadas a "begintrans" y "commit".
De todas formas el codigo correcto es el que tu has apuntado.

Saludos
Responder Con Cita
  #5  
Antiguo 06-09-2006
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 28
jachguate Va por buen camino
Cita:
Empezado por kalimero
No lo he dicho porque doy por supuesto que el interesado ya tenia claro este tema.
Pero luego hay cada pelao que solo copia y pega...
__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #6  
Antiguo 07-09-2006
Avatar de lucasarts_18
lucasarts_18 lucasarts_18 is offline
Miembro
 
Registrado: mar 2005
Ubicación: Villa Alemana,Chile
Posts: 1.087
Poder: 21
lucasarts_18 Va por buen camino
Cita:
Empezado por jachguate

yo lo dejaría como:


Código Delphi [-]
Conexion.StartTransaction;
try
HacerTodoLoQueSeQuiera;
Conexion.Commit;
except
Conexion.Rollback;
raise; //esta línea eleva nuevamente la excepción original después del rollback
end;




Hasta luego.

No entiendo del todo lo que te refieres con HacerTodoLoQueSeQuiera;
¿Realmente es poner todos los procedimientos delphi que tengo mas arriba en uno solo?

Con referente a tu último comentario, creo que no esta acorde a un forista que tiene más de 600 mensajes y que es motivo claro de un hecho de aprender y no salir del apuro...

Hasta Luego y gracias...
__________________
No todo es como parece ser...
Responder Con Cita
  #7  
Antiguo 07-09-2006
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 28
jachguate Va por buen camino
Cita:
Empezado por lucasarts_18
No entiendo del todo lo que te refieres con HacerTodoLoQueSeQuiera;
¿Realmente es poner todos los procedimientos delphi que tengo mas arriba en uno solo?
No me refería a poner todo en uno solo, en realidad HacerTodoLoQueSeQuiera es eso... podes llamar a procedimientos, funciones, etc. Tantos como querras.

Cita:
Empezado por lucasarts_18
Con referente a tu último comentario, creo que no esta acorde a un forista que tiene más de 600 mensajes y que es motivo claro de un hecho de aprender y no salir del apuro...

Hasta Luego y gracias...
Lamento no haber sido explicito y dar pie al malentendido, pero en realidad no me refería a vos. Te explico: Yo soy de los que creen que toda respuesta dada en estos foros se está dando en realidad a la comunidad, pues hay y habrán otros que un día se toparán con este tema dentro de una búsqueda... y dentro de esos, seguramente habrá algun pelao de esos que solo copian y pegan. Creeme que después de reponder, me quedé pensando también que esos pelaos, seguramente no llegarán a leer mi mensaje..

Saludos.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #8  
Antiguo 08-09-2006
Avatar de lucasarts_18
lucasarts_18 lucasarts_18 is offline
Miembro
 
Registrado: mar 2005
Ubicación: Villa Alemana,Chile
Posts: 1.087
Poder: 21
lucasarts_18 Va por buen camino
Cita:
Empezado por jachguate
Lamento no haber sido explicito y dar pie al malentendido, pero en realidad no me refería a vos. Te explico: Yo soy de los que creen que toda respuesta dada en estos foros se está dando en realidad a la comunidad, pues hay y habrán otros que un día se toparán con este tema dentro de una búsqueda... y dentro de esos, seguramente habrá algun pelao de esos que solo copian y pegan. Creeme que después de reponder, me quedé pensando también que esos pelaos, seguramente no llegarán a leer mi mensaje..

Gracias por la aclaración, y gracias a ambos por resolver mi duda...

Hasta Luego -
__________________
No todo es como parece ser...
Responder Con Cita
  #9  
Antiguo 08-11-2010
Avatar de cacu
cacu cacu is offline
Miembro
 
Registrado: dic 2005
Ubicación: Chile
Posts: 132
Poder: 19
cacu Va por buen camino
tarde

Este problema podria tratarse con procedimientos anidados.
por otro lado puedes captutar el error en el mismo procedimiento
if @@erro<> o goto un_error:

un_error:
rolback
return(1);

aqui ya con la devolucion 1 puedes gestionar este erro

tarde la respuesta. jajaj y ademas no se si hubiese servido en el contextp de esta necesidad
Responder Con Cita
  #10  
Antiguo 08-11-2010
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 28
jachguate Va por buen camino
Cita:
Empezado por cacu Ver Mensaje
por otro lado puedes captutar el error en el mismo procedimiento
if @@erro<> o goto un_error:

un_error:
rolback
return(1);

aqui ya con la devolucion 1 puedes gestionar este erro

Francamente nunca he sido de la idea de hacer un rollback dentro de un procedimiento dentro de la propia base de datos.. no solo no es soportado por todos los motores, sino deja poca oportunidad para la re-utilización de código, ya que es indefinido (o al menos varía de motor a motor) cuál será el comportamiento con posibles próximas operaciones que uno podría suponer deben ir en el contexto de la misma transacción. En mi opinión, el control de las transacciones debe ser siempre explícito y desde fuera de los procedimientos y funciones almacenados.

Mis 2 centavos.
__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
Respuesta



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
StartTransaction - Commit y Rollback Patricio Conexión con bases de datos 0 07-12-2005 13:56:27
RollBack con más de una transacción kikodelphi MS SQL Server 2 12-10-2005 20:24:25
Ejecutar un rollback micayael PHP 4 22-09-2005 15:36:54
utilizar rollback, commit en bases sql,postgres,access detybel SQL 2 23-06-2005 17:14:11
Uso adecuado de Rollback rochi Firebird e Interbase 4 20-11-2004 20:10:55


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


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