Límite de contexto de sesión de servidor Sql

c# dapper security sql-server

Pregunta

Estamos teniendo problemas para establecer y borrar los valores del contexto de la sesión.

Recibimos el siguiente error: The value was not set for key X because the total size of keys and values in the session context would exceed the 1 MB limit

Estamos utilizando asp.net core y dapper para nuestro acceso a datos.

Al abrir una conexión, ejecutamos sp_set_session_context y enviamos 4 claves. 3 que son enteros y 1 que es una cadena.

Al probar, la cadena es nula y los enteros son menos de 10.

Después de ejecutar un comando sql, establecemos los valores de contexto de la sesión como nulos, cerramos y desechamos la conexión.

Estamos usando la siguiente consulta para ver el uso de la memoria: SELECT SUM([pages_kb]) FROM [sys].[dm_os_memory_cache_counters] WHERE [type] = 'CACHESTORE_SESSION_CONTEXT'

Esa consulta aún debe superar 1MB.

¿Alguien sabe por qué estamos recibiendo este error?

Respuesta aceptada

Este es un error conocido, que se ha corregido en SQL Server 2016 y 2017 . El siguiente script lo reproducirá de manera confiable:

bool unset = true;
using (var command = new SqlCommand()) {
  command.CommandText = "sp_set_session_context";
  command.CommandType = CommandType.StoredProcedure;
  command.Parameters.Add("@key", SqlDbType.NVarChar, 128);
  command.Parameters.Add("@value", SqlDbType.Variant, -1);
  for (int cycles = 0; cycles != 10; ++cycles) { 
    ++cycles;
    using (var connection = 
      new SqlConnection(@"Data Source=(localdb)\MSSqlLocalDB;Integrated Security=SSPI")
    ) {
      connection.Open();
      // Set as many values as we can
      int keys = 0;
      while (true) {
        command.Connection = connection;
        command.Parameters["@key"].Value = keys.ToString();
        command.Parameters["@value"].Value = new String(' ', 8000);
        try {
          command.ExecuteNonQuery();
          ++keys;
        } catch (SqlException e) {
          Console.WriteLine("Failed setting at {0}: {1}", keys, e.Message);
          break;
        }
      }
      if (unset) {
        // Now unset them
        for (; keys >= 0; --keys) {
          command.Connection = connection;
          command.Parameters["@key"].Value = keys.ToString();
          command.Parameters["@value"].Value = DBNull.Value;
          try {
            command.ExecuteNonQuery();
          } catch (SqlException e) {
            Console.WriteLine("Failed unsetting at {0}: {1}", keys, e.Message);
            break;
          }
        }
      }
    }
  }
}

Salida:

Configuración fallida en 125: el valor no se estableció para la clave '125' porque el tamaño total de las claves y valores en el contexto de la sesión excedería el límite de 1 MB.
Configuración fallida en 120: el valor no se estableció para la clave '120' porque el tamaño total de las claves y valores en el contexto de la sesión excedería el límite de 1 MB.
Configuración fallida en 115: el valor no se estableció para la clave '115' porque el tamaño total de las claves y valores en el contexto de la sesión excedería el límite de 1 MB.
Configuración fallida en 110: el valor no se estableció para la clave '110' porque el tamaño total de las claves y valores en el contexto de la sesión excedería el límite de 1 MB.
Configuración fallida en 105: el valor no se estableció para la clave '105' porque el tamaño total de las claves y valores en el contexto de la sesión excedería el límite de 1 MB.

El tamaño de contexto disponible disminuye con cada ciclo. Si continúa durante el tiempo suficiente, se reducirá a un valor mínimo (no necesariamente 0). En este punto, consultar sys.dm_os_memory_cache_counters muestra que hay mucho menos de 1 MB en uso, pero aún así, no se puede establecer más contexto de sesión.

Este error se ha corregido en SQL Server 2016 SP1 CU8 y SQL Server 2017 CU6. (El parche menciona la eliminación del problema de memoria si usa un valor NULL para el parámetro clave , pero usar un valor NULL para la clave no está permitido en primer lugar y generará un error incluso en versiones anteriores. De acuerdo con mis pruebas se ha solucionado por valores de desconexión).

Para versiones anteriores, hay al menos dos soluciones:

  • no establezca los valores en NULL cuando haya terminado, deje el motor para despejarlos. En el script anterior, si establece unset en false , observará que no se filtra ningún contexto de sesión.
  • use un valor centinela que no sea NULL para marcar valores "eliminados", como una cadena vacía.


Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué