Compartir a través de


Instrucciones para la lógica de reintento de transacciones en tablas con optimización para memoria

Hay varias condiciones de error que aparecen con las transacciones que tienen acceso a tablas optimizadas para memoria.

    1. La transacción actual intentó actualizar un registro que se ha actualizado desde que la transacción se inició.
    1. La transacción actual no pudo confirmarse debido a un error repetible de validación de lectura.
    1. La transacción actual no pudo confirmarse debido a un error serializable de validación.
    1. Una transacción anterior a la transacción actual realizada en una dependencia se ha anulado y la transacción actual ya no puede confirmarse.

Una causa común de estos errores son las interferencias entre transacciones que se ejecutan simultáneamente. La acción correctora común es reintentar la transacción.

Para obtener más información sobre estas condiciones de error, vea la sección detección de conflictos, validación y confirmación de comprobaciones de dependencia en transacciones en Memory-Optimized tablas.

Los interbloqueos (código de error 1205) no pueden aparecer en las tablas optimizadas para memoria. Los bloqueos no se utilizan en las tablas optimizadas para memoria. Sin embargo, si la aplicación ya contiene lógica de reintento para los interbloqueos, la lógica existente se puede ampliar para incluir los nuevos códigos de error.

Consideraciones sobre el reintento

Las aplicaciones suelen encontrar conflictos entre las transacciones y tienen que implementar lógica de reintento para resolverlos. El número de conflictos encontrado depende de varios factores:

  • Contención de filas individuales. La posibilidad de conflictos aumenta a medida que aumenta el número de transacciones que intentan actualizar la misma fila.

  • Número de filas leídas por transacciones REPEATABLE READ. Cuantas más filas se lean, mayor es la probabilidad de que algunas de estas filas sean actualizadas por transacciones simultáneas. Esto causa errores de validación de lectura repetible.

  • Tamaño de los intervalos de examen que utilizan las transacciones SERIALIZABLE. Cuanto mayores sean los intervalos de examen, mayor es la posibilidad de que las transacciones simultáneas presenten filas fantasma, ocasionando errores en la validación serializable.

    Es difícil para una aplicación evitar estos conflictos, que requieren lógica de reintento.

Importante

Las transacciones de lectura/escritura que tienen acceso a tablas optimizadas para memoria requieren lógica de reintento.

Consideraciones para las transacciones de solo lectura y los procedimientos almacenados compilados de forma nativa

Las transacciones de solo lectura que abarcan la ejecución de un procedimiento almacenado compilado de forma nativa no requieren la validación de las transacciones REPEATABLE READ y SERIALIZABLE. No pueden producirse conflictos de escritura porque una transacción es de solo lectura.

Sin embargo, los errores de dependencia pueden seguir apareciendo. Los errores de dependencia son más extraños que los errores resultantes de conflictos. Por tanto, en muchos casos, no se requiere una lógica de reintento específica para las transacciones de solo lectura que abarcan ejecuciones únicas de procedimientos almacenados compilados de forma nativa.

Consideraciones para las transacciones de solo lectura y las transacciones entre contenedores

Las transacciones de solo lectura entre contenedores, que son las transacciones que se inician fuera del contexto de un procedimiento almacenado compilado de forma nativa, no realizan la validación si se tiene acceso a todas las tablas optimizadas para memoria bajo aislamiento SNAPSHOT. Sin embargo, cuando se tiene acceso a tablas optimizadas para memoria con el aislamiento REPEATABLE READ o SERIALIZABLE, la validación se realiza en tiempo de confirmación. En este caso, puede ser necesaria lógica de reintento.

Para obtener más información, vea la sección sobre transacciones entre contenedores en niveles de aislamiento de transacciones.

Implementar lógica de reintento

Como ocurre con todas las transacciones que tienen acceso a tablas optimizadas para memoria, se debe considerar el uso de lógica de reintentos para controlar los posibles errores, como conflictos de escritura (código de error 41302) o errores de dependencia (código de error 41301). En la mayoría de las aplicaciones la tasa de error será baja, pero sigue siendo necesario controlar los errores reintentando la transacción. He aquí dos maneras sugeridas de implementar lógica de reintentos:

  • Reintentos del lado cliente. Los intentos del lado cliente son la mejor manera de implementar lógica de reintentos en el caso general. La aplicación cliente detecta el error producido por la transacción y reintenta la transacción. Si una aplicación cliente existente tiene lógica de reintentos para controlar los interbloqueos, puede ampliar la aplicación para controlar los nuevos códigos de error.

  • Mediante un procedimiento almacenado contenedor. El cliente llama a un procedimiento almacenado transact-SQL interpretado que llama al procedimiento almacenado compilado de forma nativa o ejecuta la transacción. Después, el procedimiento contenedor usa lógica try/catch para detectar el error y reintentar la llamada al procedimiento si es necesario. Es posible que se devuelvan resultados al cliente antes del error y que el cliente no sepa cómo descartarlos. Por tanto, para estar seguros, es mejor usar este método solo con procedimientos almacenados compilados de forma nativa que no devuelven ningún conjunto de resultados al cliente.

La lógica de reintento se puede implementar en Transact-SQL o en el código de la aplicación en el nivel medio.

Dos posibles razones para considerar la lógica de reintento son:

  • La aplicación cliente tiene lógica de reintento para otros códigos de error, como 1205, que puede ampliar.

  • Los conflictos son raros y es importante reducir la latencia de un extremo a otro mediante la ejecución preparada. Para obtener más información sobre cómo ejecutar directamente procedimientos almacenados compilados de forma nativa, vea Procedimientos almacenados compilados de forma nativa.

En el ejemplo siguiente se muestra la lógica de reintento en un procedimiento almacenado de Transact-SQL interpretado que contiene una llamada a un procedimiento almacenado compilado de forma nativa o a una transacción entre contenedores.

CREATE PROCEDURE usp_my_procedure @param1 type1, @param2 type2, ...  
AS  
BEGIN  
  -- number of retries - tune based on the workload  
  DECLARE @retry INT = 10  
  
  WHILE (@retry > 0)  
  BEGIN  
    BEGIN TRY  
  
      -- exec usp_my_native_proc @param1, @param2, ...  
  
      --       or  
  
      -- BEGIN TRANSACTION  
      --   ...  
      -- COMMIT TRANSACTION  
  
      SET @retry = 0  
    END TRY  
    BEGIN CATCH  
      SET @retry -= 1  
  
      -- the error number for deadlocks (1205) does not need to be included for   
      -- transactions that do not access disk-based tables  
      IF (@retry > 0 AND error_number() in (41302, 41305, 41325, 41301, 1205))  
      BEGIN  
        -- these error conditions are transaction dooming - rollback the transaction  
        -- this is not needed if the transaction spans a single native proc execution  
        --   as the native proc will simply rollback when an error is thrown   
        IF XACT_STATE() = -1  
          ROLLBACK TRANSACTION  
  
        -- use a delay if there is a high rate of write conflicts (41302)  
        --   length of delay should depend on the typical duration of conflicting transactions  
        -- WAITFOR DELAY '00:00:00.001'  
      END  
      ELSE  
      BEGIN  
        -- insert custom error handling for other error conditions here  
  
        -- throw if this is not a qualifying error condition  
        ;THROW  
      END  
    END CATCH  
  END  
END  

Consulte también

Descripción de las transacciones en tablas con optimización para memoria
Transacciones en tablas con optimización para memoria
Instrucciones para los niveles de aislamiento de transacciones con tablas con optimización para memoria