Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate \ JPA usage on a high concurrency web application

So we are developing a high concurrency web application that is pretty much a big multiplayer game.

Our server is using spring MVC , spring data , MySQL and JPA.

We are now discussion the methodology we should use in regard to concurrency.

One of the suggestions that came up pretty much got me out of my comfort zone:

I'm used to use the good old fashioned orm style:

 @Transactional
 @public void doSomeMagic() {
    User user = userDao.findById(id);
    user.setStuff(stuff);
    ...       
 }

now, the suggestion that came up said the following:

since the above methodology is prone to concurrency mishaps (and probably mitigated by locking mechanism), why don't we use SQL \ JPQL updates instead? why even bothering fetching the user if our only goal is to update its fields?

we could do something like this:

 userDao.updatePlayer(stuffParameters);   // "update Player p set stuffParameters...."

Now , i have some question about this methodology:

1) How common is the practice of using update queries instead of updating through the ORM alone?

2) What exactly are the pitfalls of this methodology?

3) Are there any hybrid solutions? or another alternative that i haven't spoke of?

4) Can anyone that actually used this methodology tell some of the rules \ realizations he got ?

Thanks!

like image 351
Urbanleg Avatar asked Nov 21 '25 18:11

Urbanleg


1 Answers

First of all, I'd like to mention that your good old fashioned orm style shouldn't use save() at all. Attached entities are automatically persistent. The save() call is useless. Every change made to an attached entity will be persisted at commit time (or sooner).

I'd also like to point that there are no more concurrency problems with this approach than there are with an approach consisting in using update queries. To the contrary: if optimistic locking (using @Version) is used, the old fashioned way of doing has less concurrency problems than the update query approach (which simply updates the state regardless of whether some concurrent transaction also has updated it).

Regarding your different points:

  1. Not very common, because this is much more cumbersome than just modifying the entities and let JPA handle the update queries. It's also much more complex to handle complex use cases, and makes to code look like JDBC code, which JPA allows avoiding in the first place.

  2. The pitfalls are that optimistic locking is bypassed if you use update queries, as is the first-level cache. So if you have loaded an entity and use an update query to update its state, the loaded entity will still hold the old state.

  3. You can use both approaches together. Just beware of the pitfalls I mentioned at point 2.

  4. Update queries can make sense, especially if the goal is to update many entities at once. I would only downgrade to such an approach if you have proven that you had a performance problem, and that this performance problem could be solved by using this approach. Otherwise, it's just premature optimization, which has a high productivity and robustness cost.

like image 165
JB Nizet Avatar answered Nov 24 '25 08:11

JB Nizet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!