jueves, 2 de junio de 2011

Ficheros bloqueados de SQL Server CE 4.0 en proyecto ASP.NET

Como sabréis si habéis leído anteriores post de mi blog, estamos inmersos en un proyecto de sitio web ASP.NET con SQL Server Compact Edition 4.0. Después de haber resuelto como desplegar el proyecto en un hosting compartido que no tiene instalado el runtime de SQL Server CE (utilizando también de forma opcional el espacio de nombres System.Data.Common y su factoría de proveedores), ahora nos encontramos con un nuevo problema para el que, con franqueza, no hemos encontrado una solución definitiva.

El problema está es que cuando ejecutamos una página que tiene acceso al fichero .sdf del proyecto (la base de datos de SQL CE), el proceso w3wp.exe (el worker process de ASP.NET) carga el runtime de SQL CE y cuando queremos sobreescribir el directorio \bin de nuevo en el servidor (porque por ejemplo estamos actualizando nuestra aplicación o estamos actualizando la propia versión de SQL CE – cuando llegue el momento y suba de versión, etc.), ciertos ficheros de ese runtime de SQL CE están bloqueados y no permiten la sobreescritura.

Si recordamos, tuvimos que copiar en el directorio \bin de nuestro sitio web todo el contenido de la carpeta C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private (excepto el fichero System.Data.SqlServerCe.Entity.dll). Pues bien, cuando queremos volver a subir nuestra aplicación al hosting, obtenemos un “bonito” bloqueo (esto también ocurre cuando copiamos a través de ftp, pero para el ejemplo estoy copiando en un servidor de la oficina utilizando directamente una carpeta compartida).

Si vemos en el servidor que está ocurriendo con el programa Unlocker, podemos ver que el proceso w3wp.exe tiene “pillados” algunos ficheros del runtime de SQL CE.

Para desbloquearlos sólo hemos encontrado las siguientes formas (siempre sin utilizar Unlocker o parecidos que nos parecen un pelín agresivo y además resultan inviable en un entorno de hosting compartido donde no tenemos acceso físico a la máquina):

  • Reiniciar el servicio “Servicio de publicación World Wide Web”.
  • Reciclar el grupo de aplicaciones (AppPool) de nuestra aplicación.

De hecho, el kit de la cuestión es tirar abajo el proceso w3wp.exe, así que en líneas generales, mientras lo consigas cualquier método es válido.

Si estás pensando que modificando el fichero web.config también funcionará… pues va a ser que no. Esto es porque no hay que confundir el AppPool (grupo de aplicaciones), que es quién levanta el proceso w3wp.exe, con el AppDomain (dominio de la aplicación). Si modificas el fichero web.config lo que se reiniciará será el AppDomain (igual que si modificas el fichero global.asax, etc.). Puedes ver más información en el enlace siguiente http://stackoverflow.com/questions/302110/what-causes-an-application-pool-in-iis-to-recycle

Claro está que una solución sería no copiar el directorio \bin completo cada vez que publiquemos, pero con sinceridad quiero despreocuparme de ello y no tener que recordar cada vez que subo que tengo que “excluir” ciertas carpetas y ficheros de mi directorio \bin. De este modo, la única solución digna que hemos encontrado pasa por ser nosotros mismos quienes reiniciemos el grupo de aplicaciones de nuestra aplicación desde el mismo código de nuestra aplicación, y en ese preciso instante (y antes de que nadie pida una página con acceso nuestro fichero .sdf y vuelva a dejar pillado los ficheros), subir rápidamente… La verdad es que no muy científico pero ¡no vemos otra!

Para reiniciar el grupo de aplicaciones desde código, he encontrado los siguientes enlaces. Aún no he probado este método, pero estoy en ello y será “página obligada” en cualquier proyecto ASP.NET con SQL CE 4.0

http://www.codeproject.com/KB/aspnet/AppPoolRecycle.aspx

http://terrapinstation.wordpress.com/2008/06/12/restart-iis-application-pool-from-aspnet-page/

http://www.logue.com.ar/blog/2008/02/find-and-recycle-current-application-pool-programmatically-for-iis-6/

Por otro lado, también tengo que decir (y con profunda amargura) que me estoy encontrado otros problemas con SQL CE 4.0 que me están dejando un mal sabor de boca (ya sé que CE no es SQL Express, pero en mi opinión la gente de Microsoft podía haber hecho algo más por facilitar la vida a los desarrolladores…)

  • No soporta el uso de TransactionScope. Más info aquí. Básicamente CE no soporta transacciones anidadas, y eso y TransactionScope no se llevan bien…
  • No se puede cambiar el nombre de una tabla sino es a través del complemento SQL Server Compact ToolBox.
  • No se puede cambiar el nombre de un campo.
  • No se puede cambiar el orden de los campos.
  • No se puede modificar la identidad (identity) para un campo en una tabla ya creada.
  • No se puede conectar nuestra base de datos con ninguna versión de SSMS (Sql Server Management Studio).
    Cuidado con el complemento SQL Server Compact ToolBox porque sólo tiene un editor de SQL y se perderán los cambios si se genera alguna SQL automáticamente (clic derecho en tabla, por ejemplo). Además de que el editor no está muy logrado en lo relativo a deshacer, seleccionar, etc.

En los próximos días iré contando más experiencias con CE, pero por ahora estoy en ese momento de indecisión, que no sabría si me gusta o no me gusta…

Un saludo!

No hay comentarios:

Publicar un comentario