2010-01-13 14 views
14

Estoy escribiendo una aplicación en C# que accede a una base de datos SQL Server 2005. La aplicación requiere una gran cantidad de bases de datos, e incluso si trato de optimizar todos los accesos, configurar los índices adecuados, etc., espero que tarde o temprano tenga problemas. Sé por qué ocurren los bloqueos de la base de datos, pero dudo que pueda lanzar el software sin bloqueos que ocurran en algún momento. La aplicación está utilizando Entity Framework para el acceso a la base de datos.Patrones para manejar un punto muerto SQL en C#?

¿Hay algún buen patrón para manejar SQLExceptions (interbloqueos) en el código de cliente de C#, por ejemplo, para volver a ejecutar el lote de instrucciones después de x milisegundos?

Para aclarar; No estoy buscando un método sobre cómo evitar interbloqueos en primer lugar (niveles de aislamiento, índices, orden de declaraciones, etc.) sino cómo manejarlos cuando realmente ocurren.

Respuesta

4

Este es el enfoque que tomamos en el último marco de aplicación en el que trabajé. Cuando detectamos un punto muerto, simplemente volvimos a realizar la transacción. Lo hicimos hasta 5 veces. Si después de 5 veces fallara, lanzaríamos una excepción. No recuerdo un momento en que el segundo intento haya fallado alguna vez. Lo sabríamos porque estábamos registrando toda la actividad en el código back-end. Así que sabíamos en cualquier momento que ocurría un punto muerto, y sabíamos si fallaba más de 5 veces. Este enfoque funcionó bien para nosotros.

Randy

+1

¿Puede decirme cómo realizó la nueva operación real de la transacción? ¿Pusiste un simple bucle para el código en cada lugar donde tuviste una transacción o obtuviste una solución más genérica? – martin

+1

Implementamos un bucle. Si la transacción falla, debido a una situación de punto muerto, devolvimos la transacción completa y volvimos a intentarla hasta 5 veces. –

6

he publicado un ejemplo de código para manejar exactamente esto hace un tiempo, pero hasta pareció perder mi cuenta en el ínterin así que no puedo encontrar ahora tengo miedo y no tienen la código que utilicé aquí.

Respuesta corta: envuelva la cosa en una try..catch. Si detecta un error que parece un punto muerto, duerma durante un tiempo aleatorio breve e incremente una vez más el contador. Si obtiene otro error o el contador de intentos borra su umbral, devuelva el error a la rutina de llamadas.

(Y si se puede, tratar de tapón esto en una rutina general y ejecutar la mayoría/todos los de su acceso DB a través de él los puntos muertos por lo que estamos manejando en todo el programa.) EDITAR

: Ah, enséñame ¡no usar Google! El ejemplo de código anterior I y otros dieron es en How to get efficient Sql Server deadlock handling in C# with ADO?

Cuestiones relacionadas