PDA

Ver la Versión Completa : Problema con excepsión y transacción


mpedra
11-04-2006, 20:31:24
Hola

Estoy con un problemita de excepciones que no se si es propio de esta sección del foro, pero como esto me ocurre con SQL Server, es posible que alguien ya halla lidiado con el.
Al grano;

Una aplicacion multiusuario (Delphi 5 BDE y SQL Server 2000) realiza bloqueos de registro según este esquema:

Se inicia una transacción.
Se ejecuta la consulta de bloqueo.
Se edita....


El problema que estoy teniendo es en la captura de la excepción que se produce cuando intento bloquear un registro ya bloqueado por otro usuario.
La exepción es capturada pero la transacción es concluída por ¿el BDE?.

¿Existe alguna forma de mantener viva la transacción mas allá de una excepción?

Desde ya muchas gracias.

Salu2

alapaco
11-04-2006, 20:53:10
En que instrucción te da error ?

mpedra
11-04-2006, 21:21:47
En que instrucción te da error ?

Hola,

En la base tengo:
LOCK_TIMEOT =3000

Las aplicaciones bloquean registros mediante un stored procedure.

Supongamos dos instancias de la aplicacion.
La primera bloquea el registro y comienza a editarlo.

Cuando la 2da intenta bloquear el mismo reg que en la 1ra instancia se produce una excepción. Teoricamente el código NativeError es 1222.

Mi problema es que al capturar la excepción la transacción todavia sigue activa, pero al salir del try except ya no.

==> Aqui esta el procedimiento en donde se captura la excepción:

procedure TForm1.btnEditarClick(Sender: TObject);
begin
//Llama a editar un registro
with qryModif do
begin
close;
ParamByName('pID').Value:=catCalif.fieldByName('ID').value;
ParamByName('pActualiza').Value:=1;
try
open;
except on E:EDatabaseError do
begin
ManejarErrorBloqueo(qryModif,E);
MessageDlg('El registro que desea editar, está siendo util'+
'izado por otro usuario. '+#13+#10+'Por favor i'+
'ntente la operación nuevamente mas tarde.',
mtError, [mbOK], 0);
end;
end;
end;
end;

La transacción fue iniciada antes, y lo que necesito es que apesar del error de bloqueo ésta continue viva.

alapaco
11-04-2006, 21:39:26
Y en la función ManejarErrorBloqueo haces algo con la base de datos ?

mpedra
11-04-2006, 21:57:04
Procedure TForm1.ManejarErrorBloqueo(Dataset:TDataset;E:EDatabaseError);
var
I: Integer;
x: String;
begin
if Database1.InTransaction then
MessageDlg('Todavia estoy en la transaccion', mtWarning, [mbOK], 0);
if E is EDBEngineError then
with EDBEngineError(E) do
for I := 0 to ErrorCount - 1 do
if Errors[I].NativeError <> 0 then
begin
X := X+inttostr(Errors[I].NativeError)+#13+#10;
Exit;
end;

MessageDlg(''+X, mtError, [mbOK], 0);


end;

El messageDlg que me informa que todavia estoy dentro de la transaccion me lo muestra, osea que alli todavia está la transacción en funcionamiento.

Despues de mostrar los errores, hago un rollback y me da este error:
No user transaction is currently in progress.
...

alapaco
11-04-2006, 22:09:48
Es como si al haber un error te hiciera automaticamente un rollback o un commit (esto último poco probable) por default.
Tal vez este seteado así en los componentes de base de datos, cuales usas ?

mpedra
11-04-2006, 22:13:18
TDatabase para la conexion
TQuery...

BDE

alapaco
11-04-2006, 22:24:36
La propiedad KeepConnection del TDatabase está en True ?

mpedra
11-04-2006, 22:33:32
Si está en true

Aparentemente la instancia de TDabase1 permance dentro de la transaccion fuera del try except donde capturo el error. (ya que hago un Database1.Intransaction y me da true). Pero si hago un commit o un rollback me da el error de que no tengo transaccion activa.