none
Problemas al entrar más de un usuario en una aplicación web asp.net con SQL RRS feed

  • Pregunta

  • Tengo una aplicación web que consiste en algo parecido a una tienda online. El conjunto está formado por 3 proyectos de asp.net (4.0) (en visual basic). Uno de ellos contiene las consultas a la base de datos, otro hace de web service para acceder a las consultas, y el tercero es la propia aplicación con sus páginas .aspx.

    Cuando un usuario accede a la tienda, puede navegar sin mucho problema (salvo la lentitud propia de ASP). Pero en cuanto otro usuario accede (a veces sin llega a loguearse) a donde se encuentra la tienda (.../index.aspx), la sesión se cuelga para ambos y se puede estar esperando indefinidamente.

    He probado a compilar todo en 3.5 pero sigue ocurriendo algo similar. ¿Alguna idea?

    Muchas gracias, y un saludo

    martes, 10 de enero de 2017 17:39

Respuestas

Todas las respuestas

  • hola

    >>a donde se encuentra la tienda (.../index.aspx), la sesión se cuelga para ambos y se puede estar esperando indefinidamente.

    Estas usando variables declaradas como "static" ? porque si es asi esto causa problemas de concurrencia

    >>He probado a compilar todo en 3.5 pero sigue ocurriendo algo similar

    la version del framework no tiene nada que ver

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    martes, 10 de enero de 2017 21:38
  • Hola. Muchas gracias por la respuesta.

    En el proyecto, no hay ninguna variable static. He eliminado todo el tema de carga de artículos, y he reducido la aplicación al mínimo. Simplemente navegando entre pestañas del menú, cuando entra otro usuario, se cuelga y tarda más de medio minuto en responder de nuevo.

    Un saludo

    miércoles, 11 de enero de 2017 15:15
  • Puedes mostrarnos la configuración de tu sitio web y el web.config? En tu capa de acceso a datos realizas Dispose de las conexiones empleando bloques Using? El cuelgue se da siempre que entra otro usuario a la aplicación?

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    miércoles, 11 de enero de 2017 16:02
    Moderador
  • La aplicación está alojada directamente en un servidor. Las conexiones de la base de datos empiezan con un Conexion.Open() y terminan con un Conexion.Close() en todas las funciones que realizan consultas.

    El cuelgue se da siempre que entra otro usuario, es tal cual. Puedes estar navegando 15 minutos sin parar de moverte y cuando entra otro usuario, se cuelga.

    Os dejo aquí una muestra del Web.config. Muchas gracias por vuestra ayuda.

    <?xml version="1.0"?>
    <configuration>
      <configSections>
        <section name="urlrewritingnet" restartOnExternalChanges="true" requirePermission="false" type="UrlRewritingNet.Configuration.UrlRewriteSection, UrlRewritingNet.UrlRewriter"/>
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
          <section name="B2B.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
        </sectionGroup>
      </configSections>
    
      <connectionStrings>
        <add name="B2B.My.MySettings.ConexionSql" connectionString="Data Source=(servidor);Initial Catalog=(bd);Persist Security Info=True;User ID=(user);Password=(pass)" providerName="System.Data.SqlClient"/>
      </connectionStrings>
    
      <appSettings>
        <add key="TipoBD" value="SqlServer"/>
        <!--SqlServer o Access -->
        <add key="Servidor" value="(servidor)"/>
        <add key="BBDD" value="(bd)"/>
      </appSettings>
    
      <system.web>
        <!--<httpRuntime requestValidationMode="2.0" />-->
        <compilation debug="true" batch="false" strict="false" explicit="true" targetFramework="4.0"/>
        <pages validateRequest="false" controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID">
          <namespaces>
            <clear/>
            <add namespace="System"/> 
            <add namespace="System.Collections"/>
            <add namespace="System.Collections.Specialized"/>
            <add namespace="System.Configuration"/>
            <add namespace="System.Text"/>
            <add namespace="System.Text.RegularExpressions"/>
            <add namespace="System.Web"/>
            <add namespace="System.Web.Caching"/>
            <add namespace="System.Web.SessionState"/>
            <add namespace="System.Web.Security"/>
            <add namespace="System.Web.Profile"/>
            <add namespace="System.Web.UI"/>
            <add namespace="System.Web.UI.WebControls"/>
            <add namespace="System.Web.UI.WebControls.WebParts"/>
            <add namespace="System.Web.UI.HtmlControls"/>
          </namespaces>
        </pages>
        <authentication mode="None"/>
        <customErrors defaultRedirect="error.aspx" mode="Off">
          <error statusCode="500" redirect="error500.aspx"/>
          <error statusCode="404" redirect="error404.aspx"/>
          <error statusCode="403" redirect="error403.aspx"/>
        </customErrors>
        <!--
        <httpModules>
          <add name="UrlRewriteModule" type="UrlRewritingNet.Web.UrlRewriteModule, UrlRewritingNet.UrlRewriter"/>
        </httpModules>-->
        <webServices>
          <protocols>
            <add name="HttpPost"/>
            <add name="HttpGet"/>
          </protocols>
          <soapExtensionTypes/>
        </webServices>
      </system.web>
      <applicationSettings>
        <ExitB2B.My.MySettings>
          <setting name="B2B_WS_WS" serializeAs="String">
            <value>http://localhost:2215/WS.asmx</value>
          </setting>
        </ExitB2B.My.MySettings>
      </applicationSettings>
      <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    			<dependentAssembly>
    				<assemblyIdentity name="CrystalDecisions.ReportAppServer.DataDefModel" publicKeyToken="692FBEA5521E1304" culture="neutral"/>
    				<bindingRedirect oldVersion="0.0.0.0-13.0.2000.0" newVersion="13.0.2000.0"/>
    			</dependentAssembly>
    			<dependentAssembly>
    				<assemblyIdentity name="CrystalDecisions.ReportAppServer.Controllers" publicKeyToken="692FBEA5521E1304" culture="neutral"/>
    				<bindingRedirect oldVersion="0.0.0.0-13.0.2000.0" newVersion="13.0.2000.0"/>
    			</dependentAssembly>
    			<dependentAssembly>
    				<assemblyIdentity name="CrystalDecisions.ReportAppServer.XmlSerialize" publicKeyToken="692FBEA5521E1304" culture="neutral"/>
    				<bindingRedirect oldVersion="0.0.0.0-13.0.2000.0" newVersion="13.0.2000.0"/>
    			</dependentAssembly>
    			<dependentAssembly>
    				<assemblyIdentity name="CrystalDecisions.ReportAppServer.CommLayer" publicKeyToken="692FBEA5521E1304" culture="neutral"/>
    				<bindingRedirect oldVersion="0.0.0.0-13.0.2000.0" newVersion="13.0.2000.0"/>
    			</dependentAssembly>
    			<dependentAssembly>
    				<assemblyIdentity name="CrystalDecisions.ReportAppServer.CommonObjectModel" publicKeyToken="692FBEA5521E1304" culture="neutral"/>
    				<bindingRedirect oldVersion="0.0.0.0-13.0.2000.0" newVersion="13.0.2000.0"/>
    			</dependentAssembly>
    			<dependentAssembly>
    				<assemblyIdentity name="CrystalDecisions.ReportAppServer.ReportDefModel" publicKeyToken="692FBEA5521E1304" culture="neutral"/>
    				<bindingRedirect oldVersion="0.0.0.0-13.0.2000.0" newVersion="13.0.2000.0"/>
    			</dependentAssembly>
    			<dependentAssembly>
    				<assemblyIdentity name="CrystalDecisions.ReportAppServer.ClientDoc" publicKeyToken="692FBEA5521E1304" culture="neutral"/>
    				<bindingRedirect oldVersion="0.0.0.0-13.0.2000.0" newVersion="13.0.2000.0"/>
    			</dependentAssembly>
    			<dependentAssembly>
    				<assemblyIdentity name="CrystalDecisions.ReportAppServer.CommonControls" publicKeyToken="692FBEA5521E1304" culture="neutral"/>
    				<bindingRedirect oldVersion="0.0.0.0-13.0.2000.0" newVersion="13.0.2000.0"/>
    			</dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="CrystalDecisions.Shared" publicKeyToken="692FBEA5521E1304" culture="neutral"/>
            <bindingRedirect oldVersion="0.0.0.0-13.0.2000.0" newVersion="13.0.2000.0"/>
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="CrystalDecisions.CrystalReports.Engine" publicKeyToken="692FBEA5521E1304" culture="neutral"/>
            <bindingRedirect oldVersion="0.0.0.0-13.0.2000.0" newVersion="13.0.2000.0"/>
          </dependentAssembly>
        </assemblyBinding>
      </runtime>
    </configuration>
    

    miércoles, 11 de enero de 2017 16:33
  • A mi modo de ver no hay algo raro en la configuración. Revisa el visor se eventos del servidor cuando se conecte el segundo usuario por si puedes obtener mas información

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    miércoles, 11 de enero de 2017 16:55
    Moderador
  • En el servidor no se aprecia nada. Como mucho hay un consumo del 1 o 2%, con lo que el servidor no se satura ni un poco cuando esto ocurre. 

    Tenemos una aplicación muy similar funcionando en otro servidor, que funciona bien (va lenta pero no se cuelga cuando entra otro usuario). La principal diferencia es que está en .Net Framework 2.0. y alguna diferencia en el web.config, imagino que por el tipo de compilación.

    ¿Puede ser un problema de acceso al WS aunque al invocarlo por separado no haya ningún problema? Las consultas al SQL tampoco parecen dar ningún problema. ¿Puede ser un problema de utilización de Repeaters o de un TreeView?

    Muchas gracias por vuestro tiempo.

    miércoles, 11 de enero de 2017 17:06
  • Hola #Ca-programadora

    Las aplicaciones cuando generan una conexión, usan algo que viene implícito y son las pool conecction y crea 25 conexiones, a nosotros nos paso algo similar pero ya con una mayor cantidad de conexiones, y lo solucionamos modificando estas variables en nuestra cadena de conexión, espero y te sea funcional.

    <add name="RHGC.Properties.Settings.cad" connectionString="Password=####;Persist Security Info=True;User ID=###;Initial Catalog=done_erp;Data Source=####;Pooling=false;Max Pool Size=1;" />

    Si te ha sido util, marcala como respuesta.

    Feliz día!.

    Sonrrie :) 


    Sánchez F., Erik

    miércoles, 11 de enero de 2017 18:21
  • Yo activaría en el servidor los contadores de rendiemiento de ASP.NET para realizar una monitorización.

    Cómo: Ver los contadores de rendimiento de ASP.NET disponibles en el equipo

    Qué versión de VS tienes? Una Enterprise? Lo digo porque tiene herramientas de profiling.

    Te dejo otro enlace de una herramienta de MS --> Herramientas de pruebas de esfuerzo para el servidor Web


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    jueves, 12 de enero de 2017 8:22
    Moderador
  • Muchas gracias, Erik, probaré lo que me dices.

    Imagino que te refieres a sustituir mi cadena por esa, cambiando solo los datos de Password, UserID y DataSource.

    Un saludo :)

    jueves, 12 de enero de 2017 8:24
  • Hola Sergio, muchas gracias por tu respuesta.

    Mi versión de VS es 2013 Professional. Intentaré hacer lo que dices de monitorizar el rendimiento de ASP.NET.

    Un saludo!

    jueves, 12 de enero de 2017 8:26
  • Estos son los resultados cuando entro en la aplicación, navego un poco, y entra otro usuario: Además, de vez en cuando se produce el error de la siguiente imagen (no siempre en el mismo sitio)

    jueves, 12 de enero de 2017 8:36
  • He podido observar que se produce algún error más cuando solamente hay un usuario. De todos modos, si solamente navega un usuario por la aplicación, esta funciona bien y no se cuelga. Esta es la monitorización tras navegar un poco con dos usuarios simultáneos. Gracias a todos.

    jueves, 12 de enero de 2017 8:58
  • He podido ver que los errores se producen en las partes de la aplicación en las que se realiza la carga de muchas imágenes (además estas páginas tienen paginación).

    Si elimino (comentando el código) las zonas de la aplicación en las que se cargan imágenes, el problema del cuelgue cuando entra otro usuario sigue ocurriendo (quizá está menos tiempo colgado, pero no se arregla, ni mucho menos)

    jueves, 12 de enero de 2017 9:34
  • Hola, las imágenes qué tamaño tienen? aplicas técnicas de cacheo? el servidor está suficientemente dimensionado?


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    jueves, 12 de enero de 2017 10:05
    Moderador
  • Las imágenes son todas de un máximo de 200KB. Ciertamente parece de las imágenes, pero aunque elimine las imágenes, sigue colgándose. El problema parecen los Repeater de carga de artículos. Estos repeater, contienen la imagen del artículo, el stock, el nombre y el precio. Aunque elimine la imagen sigue pasando lo mismo pero, aparentemente, sin repeater el problema se reduce casi por completo (en algunas ocasiones se cuelga pero muchísimo menos).

    ¿Puede ser por los repeater? ¿Hay otra forma de hacer la carga de imágenes?

    Mucha gracias!


    jueves, 12 de enero de 2017 10:21
  • ' Se muestran los datos según la sección
                Select Case Seccion
                    Case "INICIO"
                        muestraInicio()
                        ImgBotonCatIzd.Visible = False
                    Case "OUTLET"
                        muestraOutlet()
                        pnlDerecha.Visible = True
                    Case "CATEGORIA"
                        If Page.IsPostBack = False Then
                            CargaInicialTv(Cat1Sel, Cat2Sel, Cat3Sel, Cat4Sel, Cat5Sel)
                            TreeCategorias.ExpandDepth = 0
                        End If
                        If Request.QueryString("pagina") = Nothing Then
                            cargaArticulos(0, Categoria1Actual, Categoria2Actual, Categoria3Actual, Categoria4Actual, Categoria5Actual)
                        Else
                            cargaArticulos(Request.QueryString("pagina"), Categoria1Actual, Categoria2Actual, Categoria3Actual, Categoria4Actual, Categoria5Actual)
                        End If
                    Case "ARTICULOS"
                        If Page.IsPostBack = False Then
                            CargaInicialTv(Cat1Sel, Cat2Sel, Cat3Sel, Cat4Sel, Cat5Sel)
                            TreeCategorias.ExpandDepth = 0
                        End If
                        ' Buscador
                        If Busqueda <> "" Then
                            If Request.QueryString("pagina") = Nothing Then
                                muestraBuscador(0)
                            Else
                                muestraBuscador(Request.QueryString("pagina"))
                            End If
                        End If
                End Select

    Este es el trozo de código que carga los artículos. La función cargaArticulos() hace lo siguiente:

    Public Sub cargaArticulos(ByVal Pagina As Int32, ByVal Categoria1 As String, ByVal Categoria2 As String, ByVal Categoria3 As String, ByVal Categoria4 As String, _
                                  ByVal Categoria5 As String)
            pnlIzquierda.Visible = True
            pnlDerecha.Visible = True
            pnlIzquierda.CssClass = "panel-medio panel-separador CatIzd"
            pnlDerecha.CssClass = "panel-medio CatIzd"
            Dim PgArticulos As Paginador
            ' Obtiene articulos del webservice
            DtGrid = Ws.ArticulosCategoria(Categoria1, Categoria2, Categoria3, Categoria4, Categoria5, _
                                               "", "", Configuracion.LeeCadena("catalogo_Ordenacion"))
            ' Paginador
            PgArticulos = New Paginador(CInt(Configuracion.LeeCadena("catalogo_por_pagina")), Request.Url.Query, "catalogo.aspx", DtGrid)
            If PgArticulos.Datos.PageCount > 1 Then
                paginacion.Visible = True
            Else
                paginacion.Visible = False
            End If
            PgArticulos.GenerarPaginacion(Pagina, paginacion)
            If DtGrid IsNot Nothing Then
                If DtGrid.Rows.Count > 0 Then
                    pnlArticulosCuadricula.Visible = True
                    rptArticulosCuadricula.Visible = True
                    rptArticulosCuadricula.DataSource = PgArticulos.Datos
                    rptArticulosCuadricula.DataBind()
                Else
                    MostrarSinDatos("No existen artículos en esta categoría")
                End If
                DtGrid.Dispose()
            Else
                MostrarSinDatos("No existen artículos en esta categoría")
            End If
        End Sub

    Y así son los repeater de los artículos:

    <asp:Repeater ID="rptArticulosCuadricula" runat="server" Visible="false">
                            <ItemTemplate>
                                <div class="IniArticulo">
                                    <div class="IniIcono"><asp:HyperLink ID="hypArticulo" runat="server"><asp:Image ID="imgArticulo" runat="server" /></asp:HyperLink></div>
                                    <div class="IniDescripcion"><asp:HyperLink ID="hypArticuloDesc" runat="server"><%#Container.DataItem("DescripcionArticulo").ToString%></asp:HyperLink></div>
                                    <div class="IniAdaptable"><asp:Label ID="lblAdaptable" runat="server"></asp:Label></div>
                                    <div class="IniPrecio"><asp:Label ID="lblPrecio" runat="server" Visible="true"><%#FormatNumber(Container.DataItem("PrecioVenta"), 2)%> &euro;</asp:Label></div>
                                    <div class="PedirArticuloCuadricula"><asp:TextBox id="input_Unidades" runat="server" MaxLength="40" CssClass="catalogoCampo" ToolTip="Unidades" Text="1" Width="20px"></asp:TextBox>&nbsp;&nbsp;<asp:Button ID="BtAnadir" runat="server" Text="Añadir al pedido" CommandName="Anadir" UseSubmitBehavior="False" CssClass="boton_pq"/></div>
                                </div>
                            </ItemTemplate>
                        </asp:Repeater>

    ¿Alguna idea de por qué tanto problema? Muchas gracias de nuevo a todos :)

    jueves, 12 de enero de 2017 10:32
  • Hola,

    puedes ver el tamaño de la página una vez tenida respuesta? Has probado a deshabilitar el ViewState para el Repeater? El tamaño de las imágenes (el size, el ancho y el alto) es el mismo en todas? Lo digo para que lo establezcas en el control Image


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos


    jueves, 12 de enero de 2017 11:52
    Moderador
  • No he probado, la verdad. Probaré a desactivar el ViewState. 

    ¿Cómo puedo ver el tamaño de la página una vez tenida respuesta?

    Muchas gracias!

    jueves, 12 de enero de 2017 11:56
  • De todas formas el Hyperlink se puede mostrar como una imagen, no hace falta usar un control Image dentro.

    Prueba a poner así tu Hyperlink 

    <asp:HyperLink ID="hypArticulo" runat="server" ImageUrl="Container.DataItem("UrlImagen")"/>

    <!-- Siendo UrlImagen la dirección de la imagen que supongo tienes -->



    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    jueves, 12 de enero de 2017 12:11
    Moderador
  • No he probado, la verdad. Probaré a desactivar el ViewState. 

    ¿Cómo puedo ver el tamaño de la página una vez tenida respuesta?

    Muchas gracias!

    Hola,

    una vez te ha cargado la pagina en el browser, pulsa boton derecho del ratón y Ver Código Fuente. Cópialo y guárdalo en un archivo para verificar el tamaño. También puedes verlo pulsando F12 en el browser para ver las herramientas de desarrollo del mismo, se puede ver el tamaño en pestaña de Red o Network. Por ejemplo con Chrome (https://developer.chrome.com/devtools)


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos


    jueves, 12 de enero de 2017 12:16
    Moderador
  • La página ocupa poco, unos cuantos KB. He probado a eliminar las imágenes de la BD para que no tenga nada que cargar, y le he quitado los estilos por si podían dar problema, pero persiste...
    jueves, 12 de enero de 2017 12:19
  • La página ocupa poco, unos cuantos KB. He probado a eliminar las imágenes de la BD para que no tenga nada que cargar, y le he quitado los estilos por si podían dar problema, pero persiste...

    y en tu ambiente de desarrollo como funciona? has probado que otros usuarios (incluso tu misma desde otro navegador) accedan a la par? 

    viernes, 13 de enero de 2017 14:56