Spring Boot - how to avoid concurrent access to controller
<p>We have a Spring Boot application which is linked to various client on the field.
This application has a controller which is called from the clients and interact with the DB and with a physical switch, to turn off or on a light.</p>

<p>The problem comes when two or more clients access an API on the server, because the method checks if the light is on or off (on the DB) to change its status. It occurs that if the light is OFF, and 2 clients call the service at the same time, the first turns on the light and change the status on the db but the second access the light too, the status is OFF on the DB but the first client has already tuned on the light, so the seconds eventually shuts it down thinking to turn it on... Maybe my explanation is a little unclear, the problem is: can I tell spring to access a controller one request at the time?</p>

<p>Thanks to the answer below, we introduced pessimistic lock on the method that toggles the switch, but we continue to have a 200 status from our clients...</p>

<p>We are using spring boot + hibernate</p>

<p>now the controller has the exception for pessimistic lock               </p>

<pre><code>  try {

                                String pinName = interruttore.getPinName();
                                // logger.debug("Sono nel nuovo ciclo di
                                // gestione interruttore");
                                if (!interruttore.isStato()) { // solo se
                                                                // l'interruttore
                                                                // è
                                                                // spento

                                    GpioPinDigitalOutput relePin = interruttore.getGpio()
                                            .provisionDigitalOutputPin(RaspiPin.getPinByName(pinName));
                                    interruttoreService.toggleSwitchNew(relePin, interruttore, lit);                                                            // accendo
                                    interruttore.getGpio().unprovisionPin(relePin);
                                }



                        } catch (GpioPinExistsException ge) {
                            logger.error("Gpio già esistente");
                        } catch (PessimisticLockingFailureException pe){
                            logger.error("Pessimistic Lock conflict", pe);
                            return new ResponseEntity&lt;Sensoristica&gt;(sensoristica, HttpStatus.CONFLICT);
                        }
</code></pre>

<p><code>toggleSwitchNew</code> is as follows</p>

<pre><code>@Override
@Transactional(isolation=Isolation.REPEATABLE_READ)
public void toggleSwitchNew(GpioPinDigitalOutput relePin, Interruttore interruttore, boolean on) {
    Date date = new Date();
    interruttore.setDateTime(new Timestamp(date.getTime()));
    interruttore.setStato(on);

    String log = getLogStatus(on) + interruttore.getNomeInterruttore();
    logger.debug(log);
    relePin.high();
    try {
        Thread.sleep(200);
    } catch (InterruptedException e) {
        logger.error("Errore sleep ", e);
    }
    relePin.low();
    updateInterruttore(interruttore);
    illuminazioneService.createIlluminazione(interruttore, on);


}
</code></pre>

<p>Then we log the request status code in our clients and they alway get 200 even if they are concurrent</p>