El Rincón de Pish

octubre 18, 2007

Problemas solucionados entre C#.NET 2005 y MySQL

Filed under: Programación — rolandpish @ 4:47 pm
Tags: , , ,

Hace un tiempo atrás me vi en la necesidad de darle mantenimiento a unos sistemas de un cliente, los cuales fueron programados por otra persona en C#.NET 2005 Express Edition con bases de datos en MySql 5.0.45 Community usando el conector de .NET para MySql (MySql.Data.dll).

Los sistemas estaban funcionando de maravillas, pero comenzaron a ocurrir errores muy extraños, que ocurrían de manera muy aleatoria en diferentes secciones de los sistemas. En vista de esta situación procedí a analizar el código y me dí cuenta que no habían errores de programación en las secciones de código donde ocurrían estos errores.

Invirtiendo tiempo y mucho café haciendo labores de «debug» pude observar que el primer error ocurría dentro del método Fill() de un DataAdapter de MySql.Este era el código original del método en dicho sistema. El método se encarga básicamente de llenar un DataSet con base en una sentencia SQL:

public void sqlQueryBD(DataSet ds, string sqlQuery)
{

// NOTAS:
// La conexion con MySql ya está abierta y funcionando correctamente
// cmd es un MySqlCommand ya inicializado y listo para usar
// da es un MySqlDataAdapter ya inicializado y listo para usar
try
{

cmd.CommandType = CommandType.Text;
cmd.CommandText = sqlQuery;
ds.Clear();

ds.Tables.Clear();
da.Fill(ds); // --> Línea que provoca el error

}
catch (MySqlException ex)
{

MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

}

}

En la línea de código que ejecuta a da.Fill(ds) el error era el siguiente:

«Connection unexpectedly terminated»

Y como mencionaba más arriba, el error no siempre ocurría, sino sólo cuando le daba la gana. Y otro aspecto extraño del asunto es que realmente la conexión con la base de datos no se había abortado, porque el sistema podía seguir usando la base de datos sin ningún problema. De manera inmediata supuse que el problema se estaba dando con el conector de MySql.

Como la mayoría de las personas, procedí a buscar en Internet y pude corroborar que no sólo a mí me estaba pasando y que el problema podía ser un bug.

La única solución que pude encontrar fue atrapar el error provocado inesperadamente por el método Fill() y reintentar el bloque de código en cuestión un número máximo de veces para evitar que el sistema se enciclara y se pegara. Así que el método de arriba fue cambiado por lo siguiente:

public void sqlQueryBD(DataSet ds, string sqlQuery)
{

short maxRetries = 10;
short retries = 0;
do
{

try
{

cmd.CommandType = CommandType.Text;
cmd.CommandText = sqlQuery;ds.Clear();
ds.Tables.Clear();
da.Fill(ds); // --> Línea que provoca el error
break;

}
catch (MySqlException ex)
{

retries++; if (retries <= maxRetries) { continue; }
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;

}

} while(true)

}

Con este «workaround» ese problema específico no volvió a suceder. Sin embargo, había otro error muy parecido que también estaba sucediendo cuando se iniciaba una transacción (de igual forma, el error ocurría cuando se le daba la gana). En el momento de ejecutar la instrucción:

MiConexion.BeginTransaction();

Me salía el siguiente error:

«Connection is not open»

Y mientras me fui a preparar otro percolador lleno de café para analizar este error, de pronto supuse que este problema podría estar relacionado con el anterior. Procedí a resolver el problema usando la misma idea de incluir una porción de código para reintentar la operación, pero para mi sorpresa, el error «Connection is not open» persistió en todos los intentos. Así que el problema lo pude solucionar de esta forma: antes de iniciar una transacción, mandaba a cerrar la conexión y luego abrirla. Así, la porción de código quedó de la siguiente manera:

MiConexion.Close();
MiConexion.Open();
MiConexion.BeginTransaction();
...

En otras fuentes de Internet se mencionaba algo acerca del timeout de conexión y que eso podía también ser el causante del problema, pero no me pareció una solución viable el hecho de modificar el «connect_timeout» en la configuración de MySql.

Espero que este artículo les pueda ser de utilidad si tienen estos mismos problemas y tal vez no han llegado a ninguna solución. Por supuesto, cualquier aporte en este tema será bien recibido.

Nos vemos…

Deja un comentario »

No hay comentarios aún.

RSS feed for comments on this post. TrackBack URI

Deja un comentario

Crea un blog o un sitio web gratuitos con WordPress.com.