我有3个插入客户端的功能。我正在使用mysql的事务。我正在看这个页面中的其他帖子有相同的例外,但我的代码是正确的。问题是我第二次尝试插入客户端,我的意思是:我在Delphi中打开应用程序,正确插入一个客户端。但是其他客户端给我一个例外:远程错误:无效的事务对象。
以下是代码:
function TServerMethods1.insertarcliente( idlocalidad, DNI, cuit, cuil, cupodias: integer; descuento, cupocheques, cupopesos, cupochequestro: Double;
domicilio, nombreyape, direccion, email: string ): boolean;
var
uubicacion, upersona, ucliente: integer;
tr: tdbxTransaction;
exito: boolean;
begin
SUCURSAL.Open;
tr := SUCURSAL.BeginTransaction( );
try
begin
with qipersona do
begin
Close;
ParamByName( 'DNI' ).AsInteger := DNI;
ParamByName( 'nombreyape' ).AsString := nombreyape;
ParamByName( 'direccion' ).AsString := direccion;
ParamByName( 'email' ).AsString := email;
ExecSQL( );
Free;
end
end
except
SUCURSAL.RollbackFreeAndNil( tr );
end;
try
begin
with qicliente do
begin
Close;
ParamByName( 'idpersona' ).AsInteger := qucli.ExecSQL( );
ParamByName( 'cuit' ).AsInteger := cuit;
ParamByName( 'cuil' ).AsInteger := cuil;
ParamByName( 'deuda' ).AsFloat := 0.00;
ParamByName( 'cupodias' ).AsInteger := cupodias;
ParamByName( 'cupocheques' ).AsFloat := cupocheques;
ParamByName( 'cupopesos' ).AsFloat := cupopesos;
ParamByName( 'cupochequestro' ).AsFloat := cupochequestro;
ParamByName( 'descuento' ).AsFloat := descuento;
ExecSQL( );
Free;
SUCURSAL.CommitFreeAndNil( tr );
exito := True;
end
end
except
SUCURSAL.RollbackFreeAndNil( tr );
end;
Result := exito;
end;
function TServerMethods1.insertartelefonoscliente( numero, idtipotel: integer; descripciontel: string ): boolean;
var
tr: tdbxTransaction;
exito: boolean;
begin
SUCURSAL.Open;
if ( SUCURSAL.InTransaction = False )
then
tr := SUCURSAL.BeginTransaction( )
else
begin
try
begin
with qtelefono do
begin
Close;
ParamByName( 'numero' ).AsInteger := numero;
ParamByName( 'idtipotel' ).AsInteger := idtipotel;
ParamByName( 'descripcion' ).AsString := descripciontel;
ExecSQL( );
Free;
end;
end;
// si no se pudo
except
begin
SUCURSAL.RollbackFreeAndNil( tr );
exito := False;
end;
try
with telcli do
begin
Close;
ParamByName( 'idc' ).AsInteger := qucliente.ExecSQL( );
ParamByName( 'idt' ).AsInteger := qut.ExecSQL( );
ExecSQL( );
Free;
end;
except
SUCURSAL.RollbackFreeAndNil( tr );
exito := False;
end;
SUCURSAL.CommitFreeAndNil( tr );
end;
Result := exito;
end;
end;
function TServerMethods1.insertarubicacionescliente( idlocalidad: integer; domicilio, descripcion: string ): boolean;
var
tr: tdbxTransaction;
exito: boolean;
begin
SUCURSAL.Open;
if ( SUCURSAL.InTransaction = False )
then
tr := SUCURSAL.BeginTransaction( )
else
begin
try
with qiubicacion do
begin
Close;
ParamByName( 'idlocalidad' ).AsInteger := idlocalidad;
ParamByName( 'domicilio' ).AsString := domicilio;
ParamByName( 'descripcion' ).AsString := descripcion;
ExecSQL( );
Free;
end;
// si no se pudo
except
SUCURSAL.RollbackFreeAndNil( tr );
exito := False;
end;
try
with quper do
begin
Close;
ParamByName( 'idp' ).AsInteger := qup.ExecSQL( );
ParamByName( 'idu' ).AsInteger := quu.ExecSQL( );
// ParamByName('descripcion').AsString:=descripcion;
ExecSQL( );
Free;
end;
SUCURSAL.CommitFreeAndNil( tr );
except
SUCURSAL.RollbackFreeAndNil( tr );
exito := False;
end;
Result := exito;
end;
end;
答案 0 :(得分:0)
你声称"我的代码是对的&#34 ;;但实际上并非如此。例如:在第一种方法中,您执行以下操作:
qipersona
查询
如果 [A] 发生,那么 [B1] 和 [B2] 都会保证失败,因为您正在尝试提交或回滚已经回滚的事务 !
当 [B2] 失败时,您将在除块中获得异常,并且它会转义到外层处理程序。
要正确解决您的问题,您需要停止隐藏/吞咽异常,以便您可以查看问题的实际根本原因。
使用以下结构:
StartTransaction
try
RunQuery1
RunQuery2
...
CommitTransaction
except
RollbackTransaction
raise; //This is VERY IMPORTANT ...
//Don't swallow exceptions and you'll have
//a much easier time finding your bugs.
end;