2011-09-20 14 views
7

¿Cuáles son las reglas de cómo un contexto de datos linq-a-sql mantiene abierta la conexión de la base de datos?Gestión de conexión de base de datos de contexto de linq a sql

La pregunta surgió cuando hicimos algunas pruebas de rendimiento para un SubmitChanges() por entidad actualizada en lugar de un SubmitChanges() para todo el lote de entidades. Resultados:

Inserción 3000 artículos en una SubmitChanges() llamar ... Duración: 1318ms

Inserción de 3000 artículos en una SubmitChanges() de llamada, dentro TransactionScope ... Duración: 1280ms

Inserción de 3000 artículos en SubmitChanges individuales() llama ... Duración: 4377ms

inserción de artículos en 3000 SubmitChanges individuales() llama dentro de una transacción ... Duración: 2901ms

Tenga en cuenta que cuando se hace individuo SubmitChanges() para cada entidad cambiada, poner todo dentro de una transacción mejora el rendimiento, lo cual fue bastante inesperado para nosotros. En el analizador de servidor sql podemos ver que las llamadas individuales SubmitChanges() dentro de la transacción no restablecen la conexión de base de datos para cada llamada, a diferencia de la que no tiene la transacción.

¿En qué casos el contexto de datos mantiene la conexión abierta? ¿Hay alguna documentación detallada disponible sobre cómo maneja linq-to-sql las conexiones?

Respuesta

3

No está mostrando la imagen completa; LINQ-to-SQL cerrará una llamada al SubmitChanges en una transacción de manera predeterminada. Si está envolviéndolo con otra transacción, entonces no verá restablecer la conexión; no puede hasta que todas las de las SubmitChanges llamadas estén completas y luego cuando se haya confirmado la transacción externa.

3

Puede haber una serie de factores que podrían estar influyendo en los tiempos, además de cuando las conexiones se abren/cierran.

editar: He eliminado el bit sobre entidades rastreadas después de darme cuenta de cómo linq2sql administra las entidades en caché y las entidades sucias por separado.

Puede hacerse una buena idea de cómo se administran las conexiones bajo las cubiertas utilizando Reflector o algún otro desensamblador para examinar los métodos en la clase SqlConnectionManager. SubmitChanges llamará a ClearConnection en su proveedor de IP (normalmente SqlProvider que luego usa SqlConnectionManager) después del envío si envuelve el envío en su propia transacción, pero no si SubmitChanges es parte de una transacción más grande. Cuando la conexión se abre y cierra depende de si hay otra actividad haciendo uso del SqlConnectionManager.

+0

El DataContext rastrea los objetos cambiados, pero en el código generado por defecto (por dbml designer en este caso) usa INotifyPropertyChanging e INotifyPropertyChanged. Con los implementados, no hay necesidad de recorrer todos los objetos. De todos modos, tienes razón en que la cantidad de entidades rastreadas crece. –

0

Me molesté con esto últimamente también. Llamar a SubmitChanges 3000 veces no será una buena idea, pero dependiendo de cuán importante es que cada registro se inserte, es posible que desee hacerlo, después de todo solo toma 1000ms.

El alcance de la transacción y múltiples SubmitChanges es lo que esperaría ver. Como todavía está dentro de una transacción, esperaría que el servidor SQL manejara esto mejor, lo que parece. Una SubmitChanges y el uso explícito/implícito de TransactionScope parece dar el mismo resultado, que es de esperar. No debería haber ninguna/gran diferencia de rendimiento allí.

creo conexiones se crean cuando sea necesario, pero hay que recordar esto se agruparon dentro de su proveedor por lo menos que la cadena de conexión está cambiando, debe engancharse en el mismo grupo de conexiones que producirá el mismo rendimiento independientemente de enfoque. Desde LINQ-SQL utiliza SqlConnection detrás de las escenas, alguna información al respecto es el siguiente:

http://msdn.microsoft.com/en-us/library/8xx3tyca(VS.80).aspx

Si su después de la actuación de la fuerza bruta, mirar a mudarse a una proceedure almacenado para insertar con una explícita TransactionScope. Si eso no es lo suficientemente rápido, mira usando SqlBulkCopy. 3000 filas deben insertarse más rápido que 1000ms.

Cuestiones relacionadas