Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid concurrent access of controller method with the same session in java spring?

I would like to know how to make sure that some method in a service is accessed only once at a time per session.

I'll illustrate by a small example:

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).

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.

How can you avoid that?

What happens if you sends 2 HTTP GETs at the same time?

How can you have something consistent in your controller/service/model/database?

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.).

Note 2: the solution should not block concurrent accesses of the controller for different users.

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.

I would greatly appreciate your help! Thanks!

code example:

@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);
    }
}
like image 899
awesome Avatar asked Nov 02 '22 10:11

awesome


1 Answers

Although I wouldn't recommend it (as it basically blocks all other calls from the same user to). On most HandlerAdapter implementations you can set the property synchronizeOnSession by default this is false allowing for concurrent requests to come from the same client. When you set this property to true requests will be queued for that client.

How to set it depends on your configuration of the HandlerAdapter.

like image 56
M. Deinum Avatar answered Nov 15 '22 04:11

M. Deinum