How to prevent OptimisticLockException with Hibernate versionless optimistic locking

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… Read More

How to address the OptimisticLockException in JPA and Hibernate

Introduction Application-level repeatable reads are suitable for preventing lost updates in web conversations. Enabling entity-level optimistic locking is fairly easy. You just have to mark one logical-clock property (usually an integer counter) with the JPA @Version annotation and Hibernate takes care of the rest. The catch Optimistic locking discards all incoming changes that are relative to an older entity version. But everything has a cost and optimistic locking makes no difference. The optimistic concurrency control mechanism takes an all-or-nothing approach even for non-overlapping changes. If two concurrent transactions are changing distinct entity… Read More

Hibernate collections optimistic locking

Introduction Hibernate provides an optimistic locking mechanism to prevent lost updates even for long-conversations. In conjunction with an entity storage, spanning over multiple user requests (extended persistence context or detached entities) Hibernate can guarantee application-level repeatable-reads. The dirty checking mechanism detects entity state changes and increments the entity version. While basic property changes are always taken into consideration, Hibernate collections are more subtle in this regard. Owned vs Inverse collections In relational databases, two records are associated with a foreign key reference. In this relationship, the referenced record is the parent while… Read More

How does Hibernate guarantee application-level repeatable reads

Introduction In my previous post I described how application-level transactions offer a suitable concurrency control mechanism for long conversations. All entities are loaded within the context of a Hibernate Session, acting as a transactional write-behind cache. A Hibernate persistence context can hold one and only one reference to a given entity. The first level cache guarantees session-level repeatable reads. If the conversation spans over multiple requests we can have application-level repeatable reads. Long conversations are inherently stateful so we can opt for detached objects or long persistence contexts. But application-level repeatable reads… Read More

Logical vs physical clock optimistic locking

Introduction In this article, I’m going to explain how the logical and physical clock versioning strategies work, and why you should prefer using logical clocks for concurrency control. Optimistic locking is a viable solution for prevening lost updates when running application-level transactions. Optimistic locking requires a version column that can be represented as: a physical clock (a timestamp value taken from the system clock) a logical clock (an incrementing numeric value) This article will demonstrate why logical clocks are better suited for optimistic locking mechanisms. System time The system time is provided… Read More

How to prevent lost updates in long conversations

Introduction All database statements are executed within the context of a physical transaction, even when we don’t explicitly declare transaction boundaries (BEGIN/COMMIT/ROLLBACK). Data integrity is enforced by the ACID properties of database transactions. Logical vs Physical transactions A logical transaction is an application-level unit of work that may span over multiple physical (database) transactions. Holding the database connection open throughout several user requests, including user think time, is definitely an anti-pattern. A database server can accommodate a limited number of physical connections, and often those are reused by using connection pooling. Holding… Read More

MongoDB optimistic locking

Introduction When moving from JPA to MongoDB you start to realize how many JPA features you’ve previously taken for granted. JPA prevents “lost updates” through both pessimistic and optimistic locking. Optimistic¬†locking doesn’t end up locking anything, and it would have been better named optimistic locking-free or optimistic concurrency control because that’s what it does anyway. Lost updates So, what does it mean to “lose updates”? A real-life example would be when multiple background tasks update different attributes of some common Entity. In our example, we have a Product¬†Entity with a quantity and… Read More