Hibernate Save()方法可在事务边界外执行?相关疑问求解
Great question—this is one of those Hibernate gotchas that confuses even experienced developers, so let’s unpack each of your doubts clearly.
1. Is the claim "save() can execute outside transaction boundaries" true?
Yes, but with important context: save() can successfully persist data even when you haven’t explicitly started a transaction (like using session.beginTransaction() or @Transactional), whereas persist() will fail to write data to the database in the same scenario (or throw an exception in some cases).
2. What does "outside transaction boundaries" mean if we’re talking about physical database transactions?
You’re absolutely right—every database operation runs within a physical transaction. The phrase here doesn’t mean "without any database transaction at all"—it means without a developer-managed transaction boundary.
When you call save() without explicitly starting a Hibernate or Spring transaction, Hibernate handles the heavy lifting behind the scenes:
- It temporarily opens a physical database transaction,
- Executes the
INSERTstatement for your entity, - Immediately commits that transaction.
This is an implicit transaction managed by Hibernate, not one you defined or controlled. So when articles say "outside transaction boundaries," they’re referring to your explicit transaction scope, not the underlying database transaction that always exists.
3. What does the phrase mean if we’re talking about logical transactions (Session)?
Here, "transaction boundary" refers to an explicit Hibernate Transaction object (started via session.beginTransaction()) or a container-managed transaction (like Spring’s @Transactional), not the Session itself.
A Session is a persistence context, but it doesn’t equal an active transaction. Here’s how the two methods behave in this scenario:
- save(): Even without an explicit transaction, calling
save()triggers Hibernate to generate the entity’s primary key immediately, execute theINSERTstatement, and commit an implicit transaction. The data is written to the database right away—no need to calltransaction.commit()or wait for the Session to flush. - persist(): This method requires an active transaction context. If you call
persist()without starting a transaction, it only attaches the entity to the Session’s cache. TheINSERTwon’t run until you either start and commit a transaction, or manually callsession.flush(). If you close the Session without doing either, the data is never written to the database, and you might even get aTransientObjectException.
Quick code examples to illustrate:
save() outside explicit transaction (works):
Session session = sessionFactory.openSession(); User newUser = new User("Alice"); session.save(newUser); // Hibernate runs INSERT and commits implicit transaction session.close(); // Data is already in the database
persist() outside explicit transaction (doesn’t persist data):
Session session = sessionFactory.openSession(); User newUser = new User("Bob"); session.persist(newUser); // Only adds to Session cache, no INSERT executed session.close(); // Session closes without flushing—data is lost!
内容的提问来源于stack exchange,提问作者shanika yrs

