ویرگول
ورودثبت نام
Ali Sohrabi
Ali Sohrabi
Ali Sohrabi
Ali Sohrabi
خواندن ۲ دقیقه·۲۱ روز پیش

Rollback in Hibernate Transactions

Why Some Exceptions Trigger Rollback and Others Don’t

One of the most common sources of bugs in Spring + Hibernate applications is misunderstanding transaction rollback behavior.

Many developers assume:

“If an exception happens, the transaction will rollback.”

That assumption is wrong by default.

Let’s clarify how it really works — and how to avoid costly data inconsistencies.


The Core Rule (Spring Default)

In Spring-managed transactions (@Transactional):

🔴 Unchecked Exceptions

(RuntimeException, Error)
➡ Trigger rollback automatically

🟡 Checked Exceptions

(Exception, IOException, SQLException)
➡ DO NOT trigger rollback by default

This rule surprises many developers — especially those new to Spring.


Why Does Spring Work This Way?

This behavior is intentional and based on Java’s exception philosophy:

  • Checked exceptions
    → Often represent recoverable or business-related conditions
    → Spring assumes you might want to commit and handle them

  • Unchecked exceptions
    → Represent programming errors or system failures
    → Spring assumes the transaction is unsafe to commit


A Simple Example

@Transactional public void createUserWithCheckedException() throws IOException { userRepository.save(new User("Alice")); throw new IOException("Checked exception"); }

✅ The user WILL be saved

Now compare that with:

@Transactional public void createUserWithRuntimeException() { userRepository.save(new User("Bob")); throw new RuntimeException("Runtime exception"); }

❌ The transaction WILL rollback

Same code. Different exception type. Very different outcome.


Forcing Rollback on Checked Exceptions

You can explicitly tell Spring to rollback:

@Transactional(rollbackFor = IOException.class) public void createUserSafely() throws IOException { userRepository.save(new User("Charlie")); throw new IOException("Now it rolls back"); }

This is essential when checked exceptions should indicate transaction failure.


Preventing Rollback for Runtime Exceptions

Sometimes you want the opposite:

@Transactional(noRollbackFor = IllegalStateException.class) public void processNonCriticalFailure() { repository.save(new Entity()); throw new IllegalStateException("Non-critical issue"); }

⚠ Use this carefully — it can be dangerous if misused.


Best Practice: Use Runtime Exceptions for Transaction Failures

Most mature Spring applications follow this rule:

All exceptions that should rollback a transaction should be unchecked

Example:

public class InsufficientBalanceException extends RuntimeException { public InsufficientBalanceException(String message) { super(message); } }

Why this works well:

  • Clear intent

  • Automatic rollback

  • Cleaner service layer

  • No rollbackFor noise everywhere


A Common Anti-Pattern (Very Important)

❌ Catching exceptions inside a @Transactional method

@Transactional public void badExample() { try { repository.save(new Entity()); throw new RuntimeException(); } catch (Exception e) { // swallowed } }

✅ Transaction will commit
❌ Data may be inconsistent

If you catch an exception, Spring assumes everything is fine unless you manually mark rollback.


Hibernate vs Spring: A Quick Note

  • Pure Hibernate (Session API)
    → Any exception usually marks the transaction rollback

  • Spring + Hibernate (most projects)
    → Spring rules apply (unchecked only by default)

Understanding this difference matters when debugging legacy code.


Key Takeaways

  • ✅ Unchecked exceptions → rollback (default)

  • ⚠ Checked exceptions → commit (default)

  • 🔧 Use rollbackFor only when necessary

  • 🧠 Prefer unchecked exceptions for transactional failures

  • ❌ Don’t swallow exceptions inside transactions


If you’ve ever seen “ghost data”, partial updates, or unexpected commits — this rule is often the reason.

Understanding it once can save hours of debugging later.

💬 Have you been bitten by this behavior before?

springhibernateexception
۱
۰
Ali Sohrabi
Ali Sohrabi
شاید از این پست‌ها خوشتان بیاید