How to fix optimistic locking race conditions with pessimistic locking
Are you struggling with performance issues in your Spring, Jakarta EE, or Java EE application?
Imagine having a tool that could automatically detect performance issues in your JPA and Hibernate data access layer long before pushing a problematic change into production!
With the widespread adoption of AI agents generating code in a heartbeat, having such a tool that can watch your back and prevent performance issues during development, long before they affect production systems, can save your company a lot of money and make you a hero!
Hypersistence Optimizer is that tool, and it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, Micronaut, or Play Framework.
So, rather than allowing performance issues to annoy your customers, you are better off preventing those issues using Hypersistence Optimizer and enjoying spending your time on the things that you love!
Recap
In my previous post, I explained the benefits of using explicit optimistic locking. As we then discovered, there’s a very short time window in which a concurrent transaction can still commit a Product price change right before our current transaction gets committed.
This issue can be depicted as follows:
- Alice fetches a Product
- She then decides to order it
- The Product optimistic lock is acquired
- The Order is inserted in the current transaction database session
- The Product version is checked by the Hibernate explicit optimistic locking routine
- The price engine manages to commit the Product price change
- Alice transaction is committed without realizing the Product price has just changed
How does LockModeType.OPTIMISTIC work in JPA and Hibernate
Are you struggling with performance issues in your Spring, Jakarta EE, or Java EE application?
Imagine having a tool that could automatically detect performance issues in your JPA and Hibernate data access layer long before pushing a problematic change into production!
With the widespread adoption of AI agents generating code in a heartbeat, having such a tool that can watch your back and prevent performance issues during development, long before they affect production systems, can save your company a lot of money and make you a hero!
Hypersistence Optimizer is that tool, and it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, Micronaut, or Play Framework.
So, rather than allowing performance issues to annoy your customers, you are better off preventing those issues using Hypersistence Optimizer and enjoying spending your time on the things that you love!
Explicit optimistic locking
In my previous post, I introduced the basic concepts of Java Persistence locking.
The implicit locking mechanism prevents lost updates and it’s suitable for entities that we can actively modify. While implicit optimistic locking is a widespread technique, few happen to understand the inner workings of explicit optimistic lock mode.
Explicit optimistic locking may prevent data integrity anomalies when the locked entities are always modified by some external mechanism.
How to get a 10,000 points StackOverflow reputation
Are you struggling with performance issues in your Spring, Jakarta EE, or Java EE application?
Imagine having a tool that could automatically detect performance issues in your JPA and Hibernate data access layer long before pushing a problematic change into production!
With the widespread adoption of AI agents generating code in a heartbeat, having such a tool that can watch your back and prevent performance issues during development, long before they affect production systems, can save your company a lot of money and make you a hero!
Hypersistence Optimizer is that tool, and it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, Micronaut, or Play Framework.
So, rather than allowing performance issues to annoy your customers, you are better off preventing those issues using Hypersistence Optimizer and enjoying spending your time on the things that you love!
How it all started
Since I started the Hibernate Master Class project, focusing on best practices and well-established usage patterns. I then realized that all my previous Hibernate experience wouldn’t be enough for this task. I needed more than that.
Hibernate has a very steep learning curve and tens of new StackOverflow questions are being asked on a daily basis. With so many problems waiting to be solved, I came to realize this was a great opportunity to prove my current skills while learning some new tricks.
On 8th of May 2014, I gave my very first StackOverflow answer. After 253 days, on 16th of January 2015, I managed to get a reputation of over 10,000:
A beginner’s guide to Java Persistence locking
Are you struggling with performance issues in your Spring, Jakarta EE, or Java EE application?
Imagine having a tool that could automatically detect performance issues in your JPA and Hibernate data access layer long before pushing a problematic change into production!
With the widespread adoption of AI agents generating code in a heartbeat, having such a tool that can watch your back and prevent performance issues during development, long before they affect production systems, can save your company a lot of money and make you a hero!
Hypersistence Optimizer is that tool, and it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, Micronaut, or Play Framework.
So, rather than allowing performance issues to annoy your customers, you are better off preventing those issues using Hypersistence Optimizer and enjoying spending your time on the things that you love!
Implicit locking
In concurrency theory, locking is used for protecting mutable shared data against hazardous data integrity anomalies. Because lock management is a very complex problem, most applications rely on their data provider implicit locking techniques.
Delegating the whole locking responsibility to the database system can both simplify application development and prevent concurrency issues, such as deadlocking. Deadlocks can still occur, but the database can detect and take safety measures (arbitrarily releasing one of the two competing locks).
Why you should pay developers to learn
Are you struggling with performance issues in your Spring, Jakarta EE, or Java EE application?
Imagine having a tool that could automatically detect performance issues in your JPA and Hibernate data access layer long before pushing a problematic change into production!
With the widespread adoption of AI agents generating code in a heartbeat, having such a tool that can watch your back and prevent performance issues during development, long before they affect production systems, can save your company a lot of money and make you a hero!
Hypersistence Optimizer is that tool, and it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, Micronaut, or Play Framework.
So, rather than allowing performance issues to annoy your customers, you are better off preventing those issues using Hypersistence Optimizer and enjoying spending your time on the things that you love!
A true story
We were having a meeting with a customer and he had just presented a project idea. He wanted us to give him a draft system architecture, supporting his project technical requirements. At one point, I was telling him that incremental development requires architecture evolution as well.
When I said that finding the right architecture is also a learning process, he cut me off short of the following sentence:
Do you expect me to pay you to learn?
To save the day, I told him I was referring to the business domain, we needed to fully understand in order to provide the right architecture.
Book review – How Linux Works 2nd edition
Are you struggling with performance issues in your Spring, Jakarta EE, or Java EE application?
Imagine having a tool that could automatically detect performance issues in your JPA and Hibernate data access layer long before pushing a problematic change into production!
With the widespread adoption of AI agents generating code in a heartbeat, having such a tool that can watch your back and prevent performance issues during development, long before they affect production systems, can save your company a lot of money and make you a hero!
Hypersistence Optimizer is that tool, and it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, Micronaut, or Play Framework.
So, rather than allowing performance issues to annoy your customers, you are better off preventing those issues using Hypersistence Optimizer and enjoying spending your time on the things that you love!
The book
The book’s author is Brian Ward, who has a Ph.D. in computer science and has written several books about Linux Kernel, Vim, and VMware. The book has 17 Chapters and covers many Linux aspects, from the Operating System architecture to Bash scripting and Package Managers.
2014 – A year in review
Are you struggling with performance issues in your Spring, Jakarta EE, or Java EE application?
Imagine having a tool that could automatically detect performance issues in your JPA and Hibernate data access layer long before pushing a problematic change into production!
With the widespread adoption of AI agents generating code in a heartbeat, having such a tool that can watch your back and prevent performance issues during development, long before they affect production systems, can save your company a lot of money and make you a hero!
Hypersistence Optimizer is that tool, and it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, Micronaut, or Play Framework.
So, rather than allowing performance issues to annoy your customers, you are better off preventing those issues using Hypersistence Optimizer and enjoying spending your time on the things that you love!
Retrospective
January
In the beginning of 2014, I took the initial version of my time series MongoDB aggregation example and pass it through a multistage optimization process, from indexing to advanced data-modelling:
- MongoDB time series: Introducing the aggregation framework
- A beginner’s guide to MongoDB performance turbocharging
- MongoDB and the fine art of data modelling
February
In February, I starting developing FlexyPool, the ultimate connection pool sizing utility. This was a great opportunity to dig into Queuing Theory and the following articles capture some of my findings:
A beginner’s guide to transaction isolation levels in enterprise Java
Are you struggling with performance issues in your Spring, Jakarta EE, or Java EE application?
Imagine having a tool that could automatically detect performance issues in your JPA and Hibernate data access layer long before pushing a problematic change into production!
With the widespread adoption of AI agents generating code in a heartbeat, having such a tool that can watch your back and prevent performance issues during development, long before they affect production systems, can save your company a lot of money and make you a hero!
Hypersistence Optimizer is that tool, and it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, Micronaut, or Play Framework.
So, rather than allowing performance issues to annoy your customers, you are better off preventing those issues using Hypersistence Optimizer and enjoying spending your time on the things that you love!
Introduction
A relational database strong consistency model is based on ACID transaction properties. In this post we are going to unravel the reasons behind using different transaction isolation levels and various configuration patterns for both resource local and JTA transactions.
Isolation and consistency
In a relational database system, atomicity and durability are strict properties, while consistency and isolation are more or less configurable. We cannot even separate consistency from isolation as these two properties are always related.
The lower the isolation level, the less consistent the system will get. From the least to the most consistent, there are four isolation levels:
- READ UNCOMMITTED
- READ COMMITTED (protecting against dirty reads)
- REPEATABLE READ (protecting against dirty and non-repeatable reads)
- SERIALIZABLE (protecting against dirty, non-repeatable reads and phantom reads)
Although the most consistent SERIALIZABLE isolation level would be the safest choice, most databases default to READ COMMITTED instead. According to Amdahl’s law, to accommodate more concurrent transactions, we have to reduce the serial fraction of our data processing. The shorter the lock acquisition interval, the more requests a database can process.
JPA and Hibernate FetchType EAGER is a code smell
Are you struggling with performance issues in your Spring, Jakarta EE, or Java EE application?
Imagine having a tool that could automatically detect performance issues in your JPA and Hibernate data access layer long before pushing a problematic change into production!
With the widespread adoption of AI agents generating code in a heartbeat, having such a tool that can watch your back and prevent performance issues during development, long before they affect production systems, can save your company a lot of money and make you a hero!
Hypersistence Optimizer is that tool, and it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, Micronaut, or Play Framework.
So, rather than allowing performance issues to annoy your customers, you are better off preventing those issues using Hypersistence Optimizer and enjoying spending your time on the things that you love!
Introduction
Hibernate fetching strategies can really make a difference between an application that barely crawls and a highly responsive one. In this post, I’ll explain why you should prefer query-based fetching instead of global fetch plans.
Had this problem this morning fixed from stackoverflow than found this. Thx Vlad Mihalcea for a concise explanation !!!
— Gal Levinshtein (@gkodkod) September 17, 2018
EAGER fetching is a code smell when using #JPA and @Hibernate @vlad_mihalcea https://t.co/7NqKH0S9oG
Fetching 101
Hibernate defines four association retrieving strategies:
| Fetching Strategy | Description |
|---|---|
| Join | The association is OUTER JOINED in the original SELECT statement |
| Select | An additional SELECT statement is used to retrieve the associated entity(entities) |
| Subselect | An additional SELECT statement is used to retrieve the whole associated collection. This mode is meant for to-many associations |
| Batch | An additional number of SELECT statements is used to retrieve the whole associated collection. Each additional SELECT will retrieve a fixed number of associated entities. This mode is meant for to-many associations |
How to prevent OptimisticLockException with Hibernate versionless optimistic locking
Are you struggling with performance issues in your Spring, Jakarta EE, or Java EE application?
Imagine having a tool that could automatically detect performance issues in your JPA and Hibernate data access layer long before pushing a problematic change into production!
With the widespread adoption of AI agents generating code in a heartbeat, having such a tool that can watch your back and prevent performance issues during development, long before they affect production systems, can save your company a lot of money and make you a hero!
Hypersistence Optimizer is that tool, and it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, Micronaut, or Play Framework.
So, rather than allowing performance issues to annoy your customers, you are better off preventing those issues using Hypersistence Optimizer and enjoying spending your time on the things that you love!
Introduction
In my previous post I demonstrated how you can scale optimistic locking through write-concerns splitting.
Version-less optimistic locking is one lesser-known Hibernate feature. In this post, I’ll explain both the good and the bad parts of this approach.
Version-less optimistic locking
Optimistic locking is commonly associated with a logical or physical clocking sequence, for both performance and consistency reasons. The clocking sequence points to an absolute entity state version for all entity state transitions.
To support legacy database schema optimistic locking, Hibernate added a version-less concurrency control mechanism. To enable this feature you have to configure your entities with the @OptimisticLocking annotation that takes the following parameters:
| Optimistic Locking Type | Description |
|---|---|
| ALL | All entity properties are going to be used to verify the entity version |
| DIRTY | Only current dirty properties are going to be used to verify the entity version |
| NONE | Disables optimistic locking |
| VERSION | Surrogate version column optimistic locking |
For version-less optimistic locking, you need to choose ALL or DIRTY.






