2010-02-22 21 views
11

Así que estoy tratando de descubrir las mejores prácticas en la conexión de mi base de datos. Tengo una gran GUI .NET que sirve como interfaz para MySQL db. Actualmente abro una conexión en la carga de la aplicación y la uso para las interacciones que necesito. Sin embargo, toda la GUI tiene un único subproceso.Multithreading y conexión (es) a base de datos

Cuando empiezo a agregar BackgroundWorkers para consultas grandes y se ejecuta, me preocupa mi conexión abierta. Sé, por ejemplo, que solo puedo tener un dataReader a la vez abierto en esa conexión. Con múltiples hilos, el usuario podría intentar crear más que eso.

¿Cuáles son las ventajas/desventajas de mantener una conexión abierta para la aplicación frente a abrir una nueva conexión para cada interacción?

¿Cuáles son algunos patrones de diseño comunes para esto?

de Acción de Gracias

Jonathan

Respuesta

6

uso de un conjunto de conexiones flujos seguros y mantener las conexiones de rosca específico (no compartir conexiones a través de hilos).

Creo que el marco de conexión MySQL .NET viene con uno integrado. Si usa la misma cadena de conexión para todas las conexiones, simplemente agregue "pooling = true" a su cadena de conexión. (Source - no hay fragmento de hipervínculo, busque "agrupación" en la tabla)

El inconveniente de este enfoque es que algunos subprocesos se bloquearán hasta que haya una conexión disponible. Tendrá que dar cuenta de esto en la estructura de su programa.

1

Con una conexión abierta, debe tener el máximo rendimiento con la base de datos. Sin embargo, terminas escribiendo un código complejo en tu aplicación para compartir la conexión.

Here es un artículo sobre los patrones de intercambio de recursos. Los ejemplos están en Ada, pero estoy seguro de que puedes leerlo de todos modos.

1

Conectarse a una fuente de datos puede llevar mucho tiempo. Para minimizar el costo de apertura de conexiones, ADO.NET usa una técnica de optimización llamada agrupación de conexiones, que minimiza el costo de abrir y cerrar repetidamente las conexiones. La agrupación de conexiones se maneja de forma diferente para los proveedores de datos de .NET Framework.

de MSDN.

ver aquí Connection Pooling (ADO.NET)

3

Hay 2 maneras:

  1. conexión individual - en este caso, se crea la conexión 1 veces y se divide entre todas las solicitudes, que si un gran número de simultánea las solicitudes conducen a la pérdida de productividad y usted debe controlar el ahorro de hilo por usted mismo.

  2. Conexión por solicitud: en este caso, debe abrir la conexión y cerrarla inmediatamente después de ejecutar la solicitud. Pero el servidor puede limitar el número de conexiones abiertas simultáneamente. Aquí, la sobrecarga de crear conexiones siempre está presente, pero se resuelve utilizando la agrupación de conexiones segura para subprocesos, lo cual era una buena práctica.

Necesita analizar y predecir el comportamiento de su aplicación y seleccionar la ruta adecuada. Si tiene una aplicación simple, probablemente no necesitará usar los grupos. Si la aplicación requiere una carga seria y escalabilidad futura, sería correcto usar los pools.

0

Hemos hecho algunas pruebas antes de decidir qué camino tomar. Quiero decir entre ConnectionAlwaysOpen o ConnectAndDisconnectEachTime.

Aparentemente de .NET con SQL Server (nunca se intentó con MySQL) no hubo una penalización de rendimiento visible en ninguno de los enfoques (nada sorprendente, ya que las capas inferiores no se desconectan inmediatamente en el escenario ConnectAndDisconnectEachTime). Pero hubo una diferencia sutil que nos hizo decidir por ConnectionAlwaysOpen. El motivo fue el soporte de transacciones. Si tiene la intención de usar transacciones, entonces la conexión/desconexión NO funcionará, creo que es obvio por qué.

ConexiónAlways Por supuesto, se puede mejorar utilizando pools de conexión existentes o alguna memoria caché de pools de conexión, pero la idea básica sigue siendo la misma. Por otro lado, en la aplicación web es un poco más difícil de implementar y seguro para hilos este enfoque, pero podría valer la pena el esfuerzo.

+0

Cuando dice que el soporte de transacciones no es posible para el escenario ConnectAndDisconnect, ¿está hablando de una transacción "global" que respaldaría la reversión de todo desde que se lanzó la aplicación? De lo contrario, incluso con ConnectAndDisconnect, puede recibir soporte de transacciones. Debe organizar su código para identificar transacciones de "alto nivel" y luego usar, por ejemplo, "TransactionScope" en C# (http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx) – FrenchData

+0

@FrenchData Me incluyo hablando de transacciones de nivel medio, procedentes de la capa de lógica de negocios. Hemos probado el enfoque de TransactionScope pero no fue suficiente, rápidamente nos encontramos con problemas, porque el código de la capa intermedia se usó de diferentes maneras imprevisibles. La solución era de alguna manera un híbrido entre los dos enfoques, nuestra clase ConnectionManager soportaba ambos enfoques. Por supuesto, no hubo necesidad de transacciones desde el inicio de la aplicación, es por eso que la solución híbrida fue mejor. – AureliusMarcus

Cuestiones relacionadas