Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 01-04-2004
MiguelC MiguelC is offline
Miembro
 
Registrado: oct 2003
Ubicación: República Dominicana
Posts: 15
Poder: 0
MiguelC Va por buen camino
Problemas con StartTransaction, Commit, Roll

Saludos a todos.
Quisiera que dentro de lo posible me puedan ayudar con este pequeño problema:

Tengo un Proceso que debe insertar registros en 3 tablas con el concepto Master/Detail, y para esto inicio la base de datos (MSQL 2000) en modo Transaccional para poder utilizar Commit o Rollback, dependiendo de la eventualidad del proceso, algo como esto:

DataBase.StartTransaction;

Try
Un Query para insertar en la Tabla Master;
Otro Query para insertar en la Tabla Detalle;
Y Otro Query para insertar en otra Tabla de Detalle

Si todo esta Bien Entoces
DataBase .Commit;
Except
Si ocurre algun Error Entoces
DataBase.RollBack;

End;

El Problema:
Inserta sin problemas en la tabla Master pero cuando quiere ejecutar el Query que inserta en la tabla de Detalle entonses el proceso se cuelga, dando a entender que hay una saturación de memoria o algo así, por lo tando no se puede ejecutar el commit del proceso.

Nota: Este proceso funciona correctamente si no utilizo StartTransaction, Commit, RollBack etc. y Utilizo Delphi 5.

Gracias por su tiempo y por cualquier ayudam

Miguel Castillo
R.D.
__________________
"La unión del Código hace la Fuerza" LMCV
Responder Con Cita
  #2  
Antiguo 01-04-2004
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 23
guillotmarc Va por buen camino
Hola.

Yo más bien me inclino a que se cuelgua por un bloqueo. En inglés se llama deadlock (abrazo mortal).

Tu primer Query modifica ciertos registros, que el segundo proceso necesita leer para hacer sus propias modificaciones. Pero el registro está bloqueado al no haber finalizado la transacción, por lo que tienes una consulta que mantiene bloqueado un registro, y otra consulta que espera que se libere ese mismo registro para poder seguir el proceso.

Para poder comprobar que es este caso, configura la sesión para que cuando se encuentre un registro bloqueado, en lugar de esperar indefinidamente a que se libere el recurso, salte un error.

Para eso, antes de realizar las modificaciones lanza la siguiente sentencia (con un Query mismo)

SET @@LOCK_TIMEOUT 0

(Por defecto está a -1, también puedes poner un valor positivo, 100 milisegundos, ...)

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #3  
Antiguo 01-04-2004
MiguelC MiguelC is offline
Miembro
 
Registrado: oct 2003
Ubicación: República Dominicana
Posts: 15
Poder: 0
MiguelC Va por buen camino
Hola guillotmarc.

Hice lo que me digiste, pero aún tengo el mismo problema, talvez esté haciendolo incorrecto aquí te envio lo que hice:

Una vez inserto en el Master entonces seteo el TimeOut y luego trato de insertar en el detalle:

With Qry_set_TimeOut do
Begin
Close;
Sql.Clear;
Sql.Add('SET LOCK_TIMEOUT 1000');
ExecSQL;
Close;
End;

Luego:

Try
With StoredProc1 Do
Begin
close;
ParamByName('@admcia_codigo').AsString :=cia_cod_bas;
ParamByName('@admsuc_codigo').AsString :=suc_cod_bas;
ParamByName('@eftsol_num').AsInteger := vi_serial; //eftsol_num;
ParamByName('@eftsol_seq').AsInteger :=1; //Sec;
ParamByName('@admtrx_cod').AsString :=admtrx_cod;
ParamByName('@eftsol_valor').AsFloat :=eftsol_valor;
ParamByName('@cntcta_codigo').AsString :=cntcta_codigo;
ParamByName('@eftsol_docum').AsString :=eftsol_docum;
ParamByName('@Origen').AsInteger :=Origen;
if not Prepared Then Prepare;
ExecProc; //OJO Aqui es que se cuelga
End;

Except
With Qry_set_TimeOut do
Begin
Close;
Sql.Clear;
Sql.Add('SELECT @@LOCK_TIMEOUT');
ExecSQL;
ShowMessage('Error en el proceso, tiempo de espera = ' + Fields [0].AsString);
Close;
End;
End;


Pero sigue colgado
__________________
"La unión del Código hace la Fuerza" LMCV
Responder Con Cita
  #4  
Antiguo 01-04-2004
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 23
guillotmarc Va por buen camino
Hola.

Hace años que no utilizo SQL Server (nunca llegué a utilizar el SQL Server 2000), así que no se me ocurre mucho.

Realmente creo que tienes que mirar los bloqueos, un problema de saturación de memória lo puedes tener en un momento dado (a veces tenía problemas de este tipo, con transacciones que quedaban colgadas), pero no cada vez que ejecutas esa instrucción.

SQL Server no lleva nada bien los bloqueos. Si modificas un registro solo debería bloquear ese registro, pero te encuentras en que a pesar de que realmente solo ese registro está bloqueado, no se pueden hacer consultas sobre la tabla debido a que no se puede evaluar correctamente el WHERE en todos los registros de la tabla (uno está bloqueado).

Además estaban los bloqueos sobre los índices que utiliza la tabla, etc ... Total, que en estos Foros he visto gente que para evitar que dos usuarios puedan entrar en el mismo registro, lo bloquean mediante el mecanismo de transacciones. Realmente hay que tener mucho valor en SQL Server para hacer eso. En seguida te encuentras con tablas totalmente bloqueadas.

Justamente por varias razones como esta, dejé de utilizar SQL Server y me pasé a Interbase/Firebird (es una gozada como implementan las transacciones).

Para hacerte una idea de lo que puede estar pasando, haz un seguimiento mediante el Administrador Corporativo, de los bloqueos que tienes activos justo antes de lanzar la actualización de los detalles.

Por cierto, puedes establecer el Lock TimeOut al empezar las modificaciones (antes de insertar/modificar el maestro), no hace falta que esperas al momento de crear los detalles. Esa variable va a permanecer con ese valor durante toda la sesión (si no lo recuerdo mal).

NOTA : También puedes jugar con el ISOLATION_LEVEL, si lo bajas a un nivel como el Read Uncommited, te puedes ahorrar muchos problemas de bloqueos (aunque leerás información que puede no ser del todo coherente).

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #5  
Antiguo 01-04-2004
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 23
guillotmarc Va por buen camino
PD : Lo que tienes que buscar en el Administrador Corporativo, es si alguna de las Tablas que intervienen en el procedimiento almacenado de creación de los Detalles (incluso aunque solo sea una consulta), tiene un bloqueo activo antes de su ejecución.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
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


La franja horaria es GMT +2. Ahora son las 19:54:45.


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