Skip to content

Commit

Permalink
improve coverage of optimistic locking in the Short Guide
Browse files Browse the repository at this point in the history
  • Loading branch information
gavinking committed Dec 23, 2024
1 parent 1a8cbad commit eb47e6b
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 8 deletions.
4 changes: 1 addition & 3 deletions documentation/src/main/asciidoc/introduction/Entities.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -458,9 +458,7 @@ It's easy to specify that the initial version should be assigned the number `1`
int version = 1; // the initial version number
----

Optimistic locks are verified by checking versions.
A version check is included in the `where` clause of every SQL `update` or `delete` statement for a versioned entity.
If a version check fails--that is, if no rows are updated--Hibernate throws an `OptimisticLockException` indicating that the current session is working with stale data--that is, that the entity was updated in some other unit of work.
Almost every entity which is frequently updated should have a version attribute.

[TIP]
// .Optimistic locking in Hibernate
Expand Down
10 changes: 8 additions & 2 deletions documentation/src/main/asciidoc/introduction/Interacting.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -301,9 +301,15 @@ The persistence context is fragile.
If you receive an exception from Hibernate, you should immediately close and discard the current session. Open a new session if you need to, but throw the bad one away first.
====

One very important kind of exception which can happen when data is shared between concurrent units of work is an _optimistic lock failure_.
Optimistic locks are verified by checking <<version-attributes,versions>>.
A version check is included in the `where` clause of every SQL `update` or `delete` statement for a versioned entity.
If a version check fails--that is, if no rows are updated--Hibernate infers that the entity was updated in some other unit of work and throws an `OptimisticLockException` to indicate that the current session is working with stale data.
As with other exceptions, this loss of synchronization between the persistence context and the database means that we must discard the current session.

[CAUTION]
====
Some of these operations require slightly more care than others.
Some of these operations listed above require slightly more care than others.
When you call `detach()`, `clear()`, `flush()`, or `refresh()`, you've already strayed from the narrow path.
You didn't stray far--and you probably had a good reason for going there--but you're in territory where Hibernate just has to assume you know what you're doing.
If you start to feel that this terrain is bogging you down, consider using a <<stateless-sessions,stateless session>>.
Expand Down Expand Up @@ -1315,7 +1321,7 @@ Therefore, Hibernate has some APIs that streamline certain more complicated look
| `byMultipleIds()` | Lets us load a _batch_ of ids at the same time
|===

[WARNING]
[NOTE]
====
Since the introduction of `FindOption` in JPA 3.2, `byId()` is now much less useful.
====
Expand Down
6 changes: 3 additions & 3 deletions documentation/src/main/asciidoc/introduction/Tuning.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -924,7 +924,7 @@ When many transactions try to read and update the same data, the program might b

There's two basic approaches to data concurrency in Hibernate:

- optimistic locking using `@Version` columns, and
- optimistic locking using <<version-attributes,`@Version` columns>>, and
- database-level pessimistic locking using the SQL `for update` syntax (or equivalent).

In the Hibernate community it's _much_ more common to use optimistic locking, and Hibernate makes that incredibly easy.
Expand All @@ -938,8 +938,8 @@ Indeed, the usual practice is to avoid having transactions that span user intera

That said, there _is_ also a place for pessimistic locks, which can sometimes reduce the probability of transaction rollbacks.

Therefore, the `find()`, `lock()`, and `refresh()` methods of the reactive session accept an optional `LockMode`.
We can also specify a link:{doc-javadoc-url}/org/hibernate/LockMode.html[`LockMode`] for a query.
Therefore, the `find()`, `lock()`, and `refresh()` methods of the session accept an optional link:{doc-javadoc-url}/org/hibernate/LockMode.html[`LockMode`].
We can also specify a `LockMode` for a query.
The lock mode can be used to request a pessimistic lock, or to customize the behavior of optimistic locking:

.Optimistic and pessimistic lock modes
Expand Down

0 comments on commit eb47e6b

Please sign in to comment.