Ir al contenido


Foto

[consulta] Conflicto de concurrencia entre transacciones (firebird)


  • Por favor identifícate para responder
11 respuestas en este tema

#1 marcosp

marcosp

    Member

  • Miembros
  • PipPip
  • 26 mensajes

Escrito 01 julio 2012 - 01:26

Hola gente!
He buscado por internet informacion sobre esto, y encontre, pero no pude resolver este problema.
Tengo una base de datos firebird centralizada a la cual se accede desde un sistema que esta instalado en otras dos computadoras.
El problema es cuando la 'computadora2' intenta actualizar un registro en la base de datos que ya ha actualizado la 'computadora1'.
Me tira el siguiente error:


delphi
  1. DeadLock
  2. update conflicts with concurrent transactions update



Este conflicto se da cuando una transaccion intenta escribir sobre un registro que esta siendo utilizado por otra transaccion.

El siguiente es el codigo que utilizo para los abm de las tablas


delphi
  1. procedure TDMCon.abm(SQL: string);
  2. begin
  3.   sqlcons.Transaction:=self.transaccion;
  4.   sqlcons.SQL.Clear;
  5.   sqlcons.SQL.Text:=SQL;
  6.   try
  7.     sqlcons.ExecSQL;
  8.     transaccion.Commit;
  9.     sqlcons.close;
  10.   Except
  11.     showmessage('No se pudo realizar la transaccion con la base de datos');
  12.   end;
  13. end;



El tema es que la primer transaccion (computadora1) ya a realizado los cambios en la base de datos y deberia estar cerrada (transaccion.Commit), por lo tanto la segunda transaccion (computadora2) no tendria que tener problemas en utilizar dicho registro.

Espero que se entienda lo que trate de preguntar jeje..

bueno, gracias de antemano.. saludos!
  • 0

#2 mightydragon_lord

mightydragon_lord

    Advanced Member

  • Miembros
  • PipPipPip
  • 73 mensajes

Escrito 01 julio 2012 - 01:30

asegurate que la transacción tenga la propiedad action en caCommit y que se encuentre activa, saludos.
  • 0

#3 marcosp

marcosp

    Member

  • Miembros
  • PipPip
  • 26 mensajes

Escrito 01 julio 2012 - 02:10

si, la transaccion esta activa y action=caCommit..

Segun estuve leyendo, al realizar el commit de una transaccion, esta confirma el update de los datos en la base de datos y se cierra. Pero, aparentemente, en mi caso sigue abierta (activa) y por eso ocurre el conflicto de concurrencia.

No puedo encontrarle la vuelta.
  • 0

#4 mightydragon_lord

mightydragon_lord

    Advanced Member

  • Miembros
  • PipPipPip
  • 73 mensajes

Escrito 01 julio 2012 - 02:43

regalanos todas las propiedades que tienes configuradas en los controles de acceso a datos, es probable que algo esté causando esto, como opr ejemplo los params de la conexión.
  • 0

#5 marcosp

marcosp

    Member

  • Miembros
  • PipPip
  • 26 mensajes

Escrito 01 julio 2012 - 03:11

Tengo los componentes de bases de datos en un DataModule

La conexion a la base de datos la realizo al iniciar el sistema con el siguiente procedimiento


delphi
  1. function TDMCon.ini_con(bd: string):boolean;
  2. var
  3.   ini:TIniFile;
  4. begin
  5.   ini:=TIniFile.Create(ExtractFilePath(application.ExeName)+'/app.ini');
  6.   conexion.HostName:=ini.ReadString('servidor','nombre','0');
  7.   conexion.DatabaseName:=ini.ReadString('servidor','ruta','0')+bd;
  8.   conexion.UserName:='sysdba';
  9.   conexion.Password:='masterkey';
  10.   conexion.LoginPrompt:=false;
  11.   ini.Free;
  12.   try
  13.     conexion.Open;
  14.     result:=true;
  15.   except
  16.     result:=false;
  17.   end;
  18. end;               



Las consultas a la base de datos (solo lectura) con


delphi
  1. procedure TDMCon.consulta(SQL: string);
  2. begin
  3.   sqlcons.Transaction:=self.transaccion;
  4.   sqlcons.SQL.Clear;
  5.   sqlcons.SQL.Text:=SQL;
  6.   try
  7.     sqlcons.Open;
  8.   except
  9.     showmessage('No se pudo realizar la consulta a la base de datos.');
  10.   end;
  11. end;


Cada vez que realizo una de estas consultas, luego la cierro con


delphi
  1. procedure TDMCon.cerrarconsulta();
  2. begin
  3.   sqlcons.Close;
  4. end;



Y las consultas de escritura (insert, update y delete) con


delphi
  1. procedure TDMCon.abm(SQL: string);
  2. begin
  3.   sqlcons.Transaction:=self.transaccion;
  4.   self.transaccion.Active:=true;
  5.   sqlcons.SQL.Clear;
  6.   sqlcons.SQL.Text:=SQL;
  7.   try
  8.     sqlcons.ExecSQL;
  9.     transaccion.Commit;
  10.     sqlcons.close;
  11.   Except
  12.     showmessage('No se pudo realizar la transaccion con la base de datos');
  13.   end;
  14. end;



Propiedades de la conexion (TIBConexion):
Se los paso en tiempo de ejecucion con el procedimiento ini_con(db:string) de arriba

Propiedades de la transaccion (TSQLTransaction):
Action=caCommit;
Params=
  wait
  rec_version
  read_commited
(Tambien probe sin ningunos de estos parametros)

Propiedades de la consulta (TSQLQuery):
Tienen los valores predeterminados, salvo 'AutoCalcFields' que esta como False (no se que sera esto, pero aparece 'False' en negrita, lo que significa que no es el valor predeterminado)





  • 0

#6 mightydragon_lord

mightydragon_lord

    Advanced Member

  • Miembros
  • PipPipPip
  • 73 mensajes

Escrito 01 julio 2012 - 04:29

Prueba por favor quitando el contenido de la propiedad params del TIBConnection, actualmente yo las dejo vacías y no me presenta problema alguno, casualmente cuando haces lo mismo con FlameRobin, genera error en la aplicación si la transacción no se ha confirmado en FlameRobin, nunca encontré el por que, pero cuando lo he hecho entre aplicaciones únicamente no me falla, casualmente nunca lleno los params y dejo el Transaction como lo tienes, saludos.
  • 0

#7 marcosp

marcosp

    Member

  • Miembros
  • PipPip
  • 26 mensajes

Escrito 01 julio 2012 - 04:46

si si.. ya he probados sin esos parametros.. Primeramente me daba este error de concurrencia de transacciones sin tener esos parametros. Despues de buscar por todos lados en internet, decidi probarlos pero tampoco funciono
  • 0

#8 marcosp

marcosp

    Member

  • Miembros
  • PipPip
  • 26 mensajes

Escrito 01 julio 2012 - 05:13

Ya he solucionado el problema!!

Pasandole un parametro al componente 'transaccion' de la siguiente manera:


delphi
  1.   transaccion.Params.Text:='isc_tpb_read_committed';



El parametro que le pasaba como 'read_commited' en realidad es 'isc_tpb_read_committed'.

Para el que le interese este tema, las dos paginas que me ayudaron son:
http://wiki.freepasc...Client.2Fserver
y
http://conferences.e...m/article/32280

mightydragon_lord gracias por responder a mi consulta!!

Saludos!




  • 0

#9 mightydragon_lord

mightydragon_lord

    Advanced Member

  • Miembros
  • PipPipPip
  • 73 mensajes

Escrito 01 julio 2012 - 05:50

Me alegra que hayas encontrado el problema =).

Saludos.
  • 0

#10 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 01 julio 2012 - 06:55

Hola,
marcosp he editado tus mensajes para darle la etiqueta correspondiente. Te voy a pedir que utilices la etiqueta delphi en cuanto coloques código delphi y la etiqueta code. Contamos con variadas etiquetas: delphi, php, c++, c#, asm, sql.

Saludos,
  • 0

#11 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 01 julio 2012 - 07:04

Respecto al problema que tuviste no está precisamente en el read commited sino más bien en la combinación con wait. El dead lock se da porque dos o más transacciones se quedan esperando a que la otra termine y confirme. Como ambas transacciones se quedan esperando en un ciclo vicioso el motor lo detecta y lanza la advertencia. La solución que tiene es matar a una de ellas.

Recomiendo la lectura del artículo Transacciones disponible en la sección de descargas que explica el uso y configuración de los niveles de aislamiento y sobre el manejo de las transacciones.

Saludos,
  • 0

#12 Nikolas

Nikolas

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 604 mensajes
  • LocationMar del Plata / Bs As / Argentina

Escrito 22 agosto 2012 - 08:04

Ya he solucionado el problema!! Pasandole un parametro al componente 'transaccion' de la siguiente manera:


delphi
  1.   transaccion.Params.Text:='isc_tpb_read_committed';


gracias, otro problema solucionado.  ;)
  • 0




IP.Board spam blocked by CleanTalk.