Saltar al contenido

Spring Boot: cómo evitar el acceso simultáneo al controlador

Luego de mucho luchar hemos encontrado el arreglo de esta dificultad que muchos los lectores de este sitio web tienen. Si tienes algún detalle que compartir no dudes en compartir tu comentario.

Solución:

Este es un problema de bloqueo clásico. Puede usar el bloqueo pesimista: al permitir que solo un cliente opere en los datos a la vez (exclusión mutua) o el bloqueo optimista: al permitir que varios clientes simultáneos operen con los datos pero que solo el primer confirmador tenga éxito.

Hay muchas maneras diferentes de hacerlo dependiendo de la tecnología que esté utilizando. Por ejemplo, una forma alternativa de resolverlo sería utilizando el nivel de aislamiento de base de datos correcto. En su caso, parece que necesita al menos un nivel de aislamiento de “lectura repetible”.

La lectura repetible asegurará que si dos transacciones simultáneas leen y cambian el mismo registro más o menos simultáneamente, solo una de ellas tendrá éxito.

En su caso, podría marcar su transacción Spring con el nivel de aislamiento adecuado.

@Transacational(isolation=REPEATABLE_READ)
public void toggleSwitch() 
    String status = readSwithStatus();
    if(status.equals("on") 
         updateStatus("off");
     else 
         updateStatus("on");
    

Si dos clientes simultáneos intentan actualizar el estado del conmutador, el primero en comprometerse ganará y el segundo siempre fallará. Solo tiene que estar preparado para decirle al segundo cliente que su transacción no tuvo éxito debido a una falla concurrente. Esta segunda transacción se retrotrae automáticamente. Usted o su cliente pueden decidir volver a intentarlo o no.

@Autowire
LightService lightService;

@GET
public ResponseEntity toggleLight()
   try 
       lightService.toggleSwitch();
       //send a 200 OK
   catch(OptimisticLockingFailureException e) 
      //send a Http status 409 Conflict!
   

Pero como estaba diciendo, dependiendo de lo que esté usando (por ejemplo, JPA, Hibernate, JDBC simple), hay varias formas de hacer esto con estrategias de bloqueo pesimistas u optimistas.

¿Por qué no solo la sincronización de subprocesos?

Otras respuestas sugeridas hasta ahora son sobre el bloqueo pesimista mediante el uso de la exclusión mutua de Java a nivel de subproceso mediante el uso de bloques sincronizados que podrían funcionar si tiene un única JVM ejecutando su código. Esta estrategia podría resultar ineficaz si tiene más de una JVM ejecutando su código o si eventualmente escala horizontalmente y agrega más nodos JVM detrás de un balanceador de carga, en cuyo caso el bloqueo de subprocesos ya no resolvería su problema.

Pero aún podría implementar el bloqueo pesimista en el nivel de la base de datos, obligando al proceso a bloquear el registro de la base de datos antes de cambiarlo y creando así una zona de exclusión mutua en el nivel de la base de datos.

Entonces, lo que importa aquí es comprender los principios de bloqueo y luego encontrar una estrategia que funcione para su escenario particular y su pila tecnológica. Lo más probable es que, en su caso, implique algún tipo de bloqueo en el nivel de la base de datos en algún momento.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *