PDA

Ver la Versión Completa : A DeadLock was Detected


jafl1965
14-10-2003, 01:00:15
Buenas a todos: Agradezco cualquier sugerencia de por donde buscar.
He aquí el problema:

Me conecto a SQLServer por BDE. Utilizo D6.
Dos componentes DataBase y varios Querys.

En el OnClick de un botón tengo:


BD1.Startransaction;
BD2.Startransaction;
try
... hago unos inserts
... hago unos updates
BD1.Commit;
BD2.Commit;

except
BD1.Rollback;
BD2.RollBack;
end ;


Esto en sentido General. Pues sucede que un usuario todo bien, con dos, tres y varios más en las pruebas todo bien.
Ahora, cuando pusimos el sistema a trabajar y entraron de golpe más de 80 usuarios empezó a salir el Error:

"A DeadLock was Detected. La transaccion (id. de proceso xxx) quedó en interbloqueo en lock recursos con otro proceso y fue elegida como sujeto del inte."

Dónde le muevo? Que cambio? Será en código de Delphi o en SQL? Cualquier sugerencia bienvenida sea.

Gracias de antemano,
José

Lepe
14-10-2003, 16:42:25
Amigo, desde luego no envidio el dolor de cabeza que vas a tener....

La cosa está clara, unas transacciones empiezan y como es lógico al hacer insert y updates, bloquea una serie de registros. Otra transaccion empieza a bloquear registros pero llega un momento en que necesita un registro que está bloqueado por la primera transaccion, y por último, la ºª transacción necesita registros que estan bloqueados por la primera así que .... Abrazo Mortal (DeadLock)


Lo unico que se me ocurre es poner un Timer para que pasado X tiempo si la transacción no se ha llevado a cabo, que haga un Rollback, para que las demas transacciones activas puedan continuar.

No conozco SQLServer, ojalá haya algo para que en caso de no poder terminar una transacción, que se pueda deshacer.

El caso del ROLLBACK creo que no es viable, ya que al deshacer una transaccion puede que necesite bloquear o desbloquear registro que han sido bloqueados por otra. SINCERAMENTE, espero equivocarme en esto último.

Lepe
14-10-2003, 16:49:56
Como ya he dicho, ni idea, pero la lógica me dice que si empiezas las transacciones en este orden:


BD1.START...
BD2.START

despues deberiás hacer :

BD2.COMMIT
BD1.COMMIT


except
BD2.ROLLBACK
BD1.ROLLBACK

¿ llevo razón ?

espero que alguien más arroje luz.

jafl1965
15-10-2003, 23:34:04
Gracias Lepe por contestar, aún seguimos teniendo problemas, de momento se detuvo la implementación del sistema. Hasta ahora lo que único que hemos hecho es poner todo en una misma BD, lo que suprime tu sugerencia, ya que abro una sola y el commit y rollback no importaria el orden.....
Los dolores de cabeza siguen.
Saludos
José

guillotmarc
16-10-2003, 15:33:44
Hola.

Un deadlock no se ocasiona unicamente por tener una aplicacion con dos procesos que entren en conflicto (2 TDatabase con transacciones abiertas). Sinó que también pueden entrar en conflicto dos usuarios en dos estaciones distintas (si los dos modifican el mismo registro dentro de sus respectivas transacciones, se puede ocasionar el abrazo mortal).

Las transacciones de SQL Server (a diferencia de las de Interbase) no están diseñadas para permanecer abiertas mientras el usuario modifica los datos. Puesto que mientras la transacción está abierta, se generan bloqueos sobre los datos hasta que no finalize la transacción.

Estos sistemas están diseñados para que las transacciones duren el minimo tiempo posible. Es decir cuando el usuario le da a guardar, es cuando abres la transacción, salvas los datos y finalizas la transacción.

Por cierto, el BDE está obsoleto, Borland no va a sacar nuevas versiones, y por lo tanto no va a actualizarlo a nuevas versiones de las bases de datos. Deberiais pensar en cambiar a ADO o dbExpress (solo Delphi 7), que són los componentes recomendados para acceder a SQL Server.

Saludos.