Let's pretend you're paranoid and doubly paranoid when it comes to multithreading. Suppose that you are doing the backend of some functionality of the application, and the application periodically pulls some methods on your servers. Everything seems to be good, but there is one but. What if your functionality directly depends on some other data, the same banal profile for example? The question is how to ensure that the script works exactly as you planned and there are no surprises? Transactions? Yes, it can be used, but what if you are a fantastic paranoid and already imagine how 10 requests to the same method from different clients fly to your server and all strictly at the same time. At this moment, the business logic of this method is tied to 100,500 different data. How do you manage all of this? You can just sync the method and that's it.But what if there are also those requests that don't make sense to keep? Here crutches already begin. I have already asked a similar question a couple of times, and it was interesting, because the task is absurdly simple and everyday (if you care that there are no logical bugs, of course). Today I decided to think about how this can be implemented very simply and without crutches. And the solution came out literally 100 lines of code.
A little illustrative example
Let's assume that there is a driver and a passenger. The driver cannot change the car until the client, for example, confirms the trip. It turns out that the client agreed to a trip with the same characteristics of the car, but in fact the driver has a different car? Don't do it! You can organize something like this:
String result = l.lock(new ArrayList<Locker.Item>() {{
add(new Locker.Item(SimpleType.TRIP, 1));
add(new Locker.Item(SimpleType.USER, 2));
}}, () -> {
//
// - - USER=2 (),
// - TRIP=1
// USER=3, :)
// :)
return " :)";
});
Elegant and simple!
Do not throw stones! )