title: How to avoid concurrent access of controller method with the same session in java spring?
body: <p>I would like to know how to make sure that some method in a service is accessed only once at a time per session.</p>
  
  <p>I'll illustrate by a small example:</p>
  
  <p>Assume we have a user in a state A (user.state = A). This user sends a HTTP GET request to our java spring controller to get a page, say /hello. Based on his status, he will be sent to either A or B. Before that, we will change his status to B (see code below).</p>
  
  <p>Now, assume again that the call dao.doSomething(); takes a lot of time. If the user sends another GET (by refreshing his browser for instance), he will call the exact same method dao.doSomething(), resulting in 2 calls.</p>
  
  <p><strong>How can you avoid that?</strong></p>
  
  <p><strong>What happens if you sends 2 HTTP GETs at the same time?</strong></p>
  
  <p><strong>How can you have something consistent in your controller/service/model/database?</strong></p>
  
  <p>Note 1: here we don't issue the 2 HTTP GETs from different browser. We just make them at the same time on the same browser (I'm aware of the max concurrent session solution, but this does not solve my problem.).</p>
  
  <p>Note 2: the solution should not block concurrent accesses of the controller for different users.</p>
  
  <p>I've read a bit about transaction on service, but I'm not sure if this is the solution. I've also read a bit on concurrency, but I still don't understand how to use it here.</p>
  
  <p>I would greatly appreciate your help! Thanks!</p>
  
  <p>code example:</p>
  
  <pre><code>@Controller
  public class UserController {    
  
      @RequestMapping(value='/hello')
      public String viewHelloPage() {
  
          // we get the user from a session attribute
          if (user.getState() = A) {
              user.setStatus(B);
              return "pageA";
          }
  
          return "pageB";
      }
  
  
  @Service
  public class UserService {
      Dao dao;
  
      @Override
      public void setStatus(User user) {
          dao.doSomething();
          user.setStatus(B);
      }
  }
  </code></pre>