From 17ea84efdcf811426268e135d0e6973d994f8954 Mon Sep 17 00:00:00 2001 From: Gavin King Date: Wed, 28 May 2025 19:13:54 +0200 Subject: [PATCH] document the rule for transaction rollback --- .../src/main/asciidoc/introduction/Interacting.adoc | 9 +++++++++ hibernate-core/src/main/java/org/hibernate/Session.java | 3 +++ .../src/main/java/org/hibernate/Transaction.java | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/documentation/src/main/asciidoc/introduction/Interacting.adoc b/documentation/src/main/asciidoc/introduction/Interacting.adoc index 096afe83fdf1..7f3cd40ef8e1 100644 --- a/documentation/src/main/asciidoc/introduction/Interacting.adoc +++ b/documentation/src/main/asciidoc/introduction/Interacting.adoc @@ -233,6 +233,14 @@ entityManager.getTransaction().setRollbackOnly(); A transaction in rollback-only mode will be rolled back when it completes. +[[after-tx-rollback]] +[IMPORTANT] +==== +Hibernate is not a software transactional memory. +When a transaction rolls back, Hibernate makes no attempt to roll back the state of objects held in memory to their state at the beginning of the transaction. +After a transaction rollback, the persistence context must be discarded, and the state of its entities must be assumed inconsistent with the state held by the database. +==== + [[persistence-operations]] === Operations on the persistence context @@ -294,6 +302,7 @@ Now, if an exception occurs while interacting with the database, there's no good Therefore, a session is considered to be unusable after any of its methods throws an exception. +[[fragile-persistence-context]] [IMPORTANT] // .The persistence context is fragile ==== diff --git a/hibernate-core/src/main/java/org/hibernate/Session.java b/hibernate-core/src/main/java/org/hibernate/Session.java index cd5c02d0f6ab..c36adc15051e 100644 --- a/hibernate-core/src/main/java/org/hibernate/Session.java +++ b/hibernate-core/src/main/java/org/hibernate/Session.java @@ -147,6 +147,9 @@ * cannot be expected to be consistent with the database after the exception occurs. *
  • At the end of a logical transaction, the session must be explicitly {@linkplain * #close() destroyed}, so that all JDBC resources may be released. + *
  • If a transaction is rolled back, the state of the persistence context and of its + * associated entities must be assumed inconsistent with the database, and the + * session must be discarded. *
  • A {@code Session} is never thread-safe. It contains various different sorts of * fragile mutable state. Each thread or transaction must obtain its own dedicated * instance from the {@link SessionFactory}. diff --git a/hibernate-core/src/main/java/org/hibernate/Transaction.java b/hibernate-core/src/main/java/org/hibernate/Transaction.java index 55784b749475..3eba0ba733d0 100644 --- a/hibernate-core/src/main/java/org/hibernate/Transaction.java +++ b/hibernate-core/src/main/java/org/hibernate/Transaction.java @@ -25,6 +25,12 @@ * {@code session.getTransaction().begin()}, and ends with a call to {@link #commit()} * or {@link #rollback()}. *

    + * When a transaction rolls back, Hibernate makes no attempt to roll back the state of + * entity instances held in memory to their state at the beginning of the transaction. + * After a transaction rollback, the current {@linkplain Session persistence context} + * must be discarded, and the state of its entities must be assumed inconsistent with + * the state held by the database. + *

    * A single session might span multiple transactions since the notion of a session * (a conversation between the application and the datastore) is of coarser granularity * than the concept of a database transaction. However, there is at most one uncommitted