2010-01-04 16 views
5

Esto es algo raro. Estoy buscando ideas sobre cómo hacer la pregunta correcta tanto como soy una solución real.ASP.net datos de usuario obteniendo cruces entre los usuarios que acceden a objetos

Tengo un sitio web y acabamos de tener un gran salto en el tráfico. Ahora, de repente, obtenemos errores de parámetros SQL a la izquierda y a la derecha. Cambiamos a un nuevo servidor sql hace unas semanas y todo ha ido bien, pero el tráfico añadido parece estar rompiéndonos.

Tengo una clase de acceso a datos que se llama cuando cada usuario intenta iniciar sesión. Se ejecuta a través de varias tareas antes de finalmente actualizar la última fecha de inicio de sesión de los usuarios y reenviarlos a la sección de administración.

Lo que estoy viendo en los registros de seguimiento sugiere que cuando estoy iniciando sesión las primeras varias tareas están usando mis datos (digamos user = birk pass = word). Pero en algún momento la clase de acceso comienza a enviar datos de otra persona que intenta iniciar sesión (digamos usuario = abcxyz)

Cada conexión que hacemos al servidor se cierra cuando terminamos con ella. Estoy anulando todos los objetos de acceso cuando termine con ellos. Pero de alguna manera, diferentes datos de usuarios de diferentes sesiones se abren camino en las instancias de otros pueblos del objeto.

No estoy usando session/application/cache/viewstate para almacenar los objetos, así que realmente no veo cómo podrían editarse entre ellos ... Es realmente raro y no estoy seguro de cómo hacerlo. investigando el problema

Esto es más o menos la clase de acceso ... Me recortado a cabo algunas de las partes que no eran dependientes de la cuestión

Imports Microsoft.VisualBasic 
Imports System.Data 
Imports System.Data.SqlClient 
Imports System.Text.RegularExpressions 
Imports System.Text 
Imports System.IO 

Namespace ABC 
    Public Class DataAccess 
     Public Class SQL 
      Dim objConnection As SqlConnection 
      Dim objAdapter As SqlDataAdapter 
      Dim objDataset As DataSet 
      Dim objTable As DataTable 
      Dim strSQL As String 
      Dim strCommandType As String 
      Shared sqlparams As List(Of param) 
      Public params As New Parameters 
      Shadows Application As HttpApplicationState = HttpContext.Current.Application 
      Shadows Server As HttpServerUtility = HttpContext.Current.Server 
      Shadows Response As HttpResponse = HttpContext.Current.Response 
      Shadows Session As HttpSessionState = HttpContext.Current.Session 

      Public Sub New() 
       Connection() 
      End Sub 

      Public Sub New(ByVal startingSql As String) 
       Connection() 
       sql = startingSql 
      End Sub 

      Private Sub Connection() 
       sqlparams = New List(Of param) 
       objConnection = New SqlConnection(ConfigurationManager.ConnectionStrings("sqlServerProd").ConnectionString) 
      End Sub 

      Public Function DataNQ(ByVal type As CommandType, Optional ByVal query As String = "") As Boolean 
       If query <> "" Then 
        sql = query 
       End If 
       Dim objCommand As SqlCommand 
       Try 
        objConnection.Open() 
       Catch ex As Exception 
        objConnection.Close() 
        objConnection.Open() 
       End Try 
       objCommand = New SqlCommand(sql, objConnection) 
       objCommand.CommandType = type 
       Dim cmd As New SqlCommand 
       HttpContext.Current.Trace.Warn(sql) 
       'HttpContext.Current.Trace.Write("Adding " & sqlparams.Count & " parameters") 
       HttpContext.Current.Trace.Warn(params.writeParams) 
       If sqlparams.Count > 0 Then 
        For Each p As param In sqlparams 
         Dim sparam As SqlParameter = p.makeParam 
         HttpContext.Current.Trace.Write(sparam.DbType.ToString, sparam.ParameterName & "=" & sparam.Value) 
         objCommand.Parameters.Add(p.makeParam) 
        Next 
        sqlparams = New List(Of param) 
       End If 
       HttpContext.Current.Trace.Warn("Successfully added " & objCommand.Parameters.Count & " parameters") 
       HttpContext.Current.Trace.Warn(params.writeParams) 

       '-- Create a SqlParameter object to hold the output parameter value 
       Dim paramRetVal As New SqlParameter("@RETURN_VALUE", SqlDbType.Int) 
       '-- Must set .Direction as ReturnValue 
       paramRetVal.Direction = ParameterDirection.ReturnValue 
       '-- Finally, add the parameter to the Command's Parameters collection 
       objCommand.Parameters.Add(paramRetVal) 
       '-- Call the sproc... 
       Dim reader As SqlDataReader = objCommand.ExecuteReader() 
       'Now you can grab the output parameter's value... 

       Dim intRetVal As Integer = Convert.ToInt32(paramRetVal.Value) 
       If intRetVal = 0 Then 
        objConnection.Close() 
        objCommand = Nothing 
        reader = Nothing 
        Return True 
       Else 
        objConnection.Close() 
        objCommand = Nothing 
        reader = Nothing 
        Return False 
       End If 
       objConnection.Close() 

      End Function 

      Public Sub freeResources() 
       sqlparams = Nothing 
       params = Nothing 
       objConnection = Nothing 
       objAdapter = Nothing 
       objDataset = Nothing 
       objTable = Nothing 
       strSQL = Nothing 
       strCommandType = Nothing 
      End Sub 

     Public Sub add(ByVal parameterName As String, ByVal dbType As System.Data.SqlDbType, ByVal size As Integer, ByRef value As Object) 
      HttpContext.Current.Trace.Write("adding param name/type/size/value", parameterName & " " & value) 
      Dim p As param 
      p = New param(parameterName, dbType, size, value) 
      p.Value = value 
      sqlparams.Add(p) 
     End Sub 

      Private Class param 
       Public name As String = Nothing 
       Public size As Integer = Nothing 
       Public type As System.Data.SqlDbType = Nothing 
       Public value As Object = Nothing 
       Public Function makeParam() As SqlParameter 
        HttpContext.Current.Trace.Warn("before make param name=" & name & " type=" & type.ToString & " value=" & value) 
        Dim p As New SqlParameter(name, type) 
        If size <> Nothing Then 
         p.Size = size 
        End If 
        p.Value = value 
        HttpContext.Current.Trace.Warn("after make param name=" & p.ParameterName & " type=" & p.DbType.ToString) 
        Return p 
       End Function 

     Public Sub New(ByVal pname As String, ByRef ptype As System.Data.SqlDbType, ByRef val As Object) 
      'HttpContext.Current.Trace.Write("new param object name/type/value name=" & pname & " type=" & ptype.ToString) 
      name = pname 
      type = ptype 
      value = val 
      'HttpContext.Current.Trace.Warn("added param name=" & name & " type=" & type.ToString) 
       End Sub 
      End Class 


     End Class 
    End Class 

ideas o pensamientos serían grandes. Gracias

+2

¿Por qué se declara "sqlparams" como compartido? –

+0

Actualicé la clase para que funcione con páginas anteriores sin necesidad de cambiar el código y al momento de dejar esto como compartido parecía encajar mejor en la necesidad de agregar una propiedad llamada sqlparams. Sin embargo, vale la pena reescribir. – Birk

Respuesta

7

Tiene su sqlparams As List(Of param) declarado como Shared. Esto significa que solo hay una instancia creada en memoria, alguna vez.

Cada referencia a ella desde cada página instanciada es usando la misma instancia de sqlparams.

Esto significa que una instancia de su página lo ha rellenado con algunos parámetros, y alguna otra instancia de la página se inicia, llama al método Connection() y lo borra. Cuando el procesador vuelve al hilo de la primera página, sqlparams ahora es nuevo, (o incluso peor, Nothing si otro hilo acaba de llamar a su método freeResources()).

Su página no es inherentemente segura para subprocesos con este código. Reemplace todas sus variables Shared con variables de instancia y debería resolver los problemas.

+0

Quité la bandera pública de sqlparams y ajusté el resto del código en consecuencia en el momento en que todo parece estar funcionando. ¡MUCHAS GRACIAS! – Birk

2

Si su clase SQL es instanciada solamente y no contiene métodos estáticos/compartidos, entonces no debería ser una parte del problema.

EDIT: Su colección de params (sqlparams) es Shared, lo que permitirá el cruce entre instancias de SQL para sus parámetros.

1

variables estáticas también causarán problemas y son como Estado de aplicación .... Creo que Shared es como en C# .... Creo que sus variables Shared es su problema. Hazles variables de instancia y debería funcionar.

Cuestiones relacionadas