πŸ”₯ Launch Offer: Interview Preparation Bundle @ β‚Ή2,499 β‚Ή9,999 β€’ 75% OFF. Offer expires in πŸ”₯ Launch Offer: Interview Preparation Bundle @ β‚Ή2,499 β‚Ή9,999 β€’ 75% OFF. Offer expires in Interview Preparation Bundle @ β‚Ή2,499 β‚Ή9,999

00:00:00 Get Bundle
home spring boot how-does-transactional-work-internally-in-spring-boot-complete-interview-guide-with-real-e-commerce-example
Interview guide Spring Boot 25 sections

How Does @Transactional Work Internally in Spring Boot? (Complete Interview Guide with Real E-commerce Example)

If you're preparing for Java Backend interviews at companies like Oracle, Walmart, Microsoft, Amazon, Deloitte, or any product-based company, one question that frequently comes up is: "How does…

Start reading
By javainterviewprep June 12, 2026 6 min read

If you’re preparing for Java Backend interviews at companies like Oracle, Walmart, Microsoft, Amazon, Deloitte, or any product-based company, one question that frequently comes up is:

“How does @Transactional work internally?”

Many developers know that it commits or rolls back database changes, but interviewers often want to understand what happens behind the scenes.

In this article, we’ll explore:

  • What @Transactional is
  • How it works internally
  • The Spring components involved
  • A real e-commerce example
  • Why self-invocation doesn’t work
  • Monolith vs Microservices usage
  • Common interview questions

Let’s begin.


What is @Transactional?

@Transactional is a Spring annotation used to manage database transactions automatically.

Its primary goal is to ensure that a group of database operations either:

  • All succeed (Commit), or
  • All fail (Rollback)

This maintains the ACID properties of a transaction and keeps your database consistent.


A Real E-commerce Example

Suppose a customer places an order.

To complete the order, your application performs three operations:

  1. Save the Order
  2. Save the Payment details
  3. Clear the Customer’s Cart
@Service
public class OrderService {

    @Transactional
    public void placeOrder(OrderRequest request) {

        orderRepository.save(order);

        paymentRepository.save(payment);

        cartRepository.clearCart(userId);
    }
}

Imagine the following happens:

  • Order is saved successfully.
  • Payment is saved successfully.
  • While clearing the cart, an exception occurs.

Without a transaction:

βœ… Order Saved

βœ… Payment Saved

❌ Cart Not Cleared

Now your database is inconsistent.

With @Transactional, Spring rolls back all previous changes, resulting in:

❌ Order Removed

❌ Payment Removed

❌ Cart remains unchanged

Everything is restored to its previous state.


How Does @Transactional Work Internally?

The biggest misconception is that Spring somehow modifies your method.

It doesn’t.

Instead, Spring uses AOP (Aspect-Oriented Programming) and the Proxy Pattern.

The actual flow looks like this:

Client
   β”‚
   β–Ό
Spring Proxy
   β”‚
   β–Ό
TransactionInterceptor
   β”‚
   β–Ό
PlatformTransactionManager
   β”‚
   β–Ό
Connection.setAutoCommit(false)
   β”‚
   β–Ό
Business Method
   β”‚
   β”œβ”€β”€ Success β†’ Commit
   └── Exception β†’ Rollback

Let’s understand each step.


Step 1: Spring Detects @Transactional

When the application starts, Spring scans all beans.

Whenever it finds:

@Transactional
public void placeOrder() {
}

it doesn’t expose the actual object.

Instead, it creates a Proxy Object.

Instead of:

Client
   β”‚
   β–Ό
OrderService

Spring creates:

Client
   β”‚
   β–Ό
OrderService Proxy
          β”‚
          β–Ό
     OrderService

This proxy intercepts every method call.


Step 2: Client Calls the Method

Suppose the controller executes:

orderService.placeOrder();

The call does not directly reach OrderService.

Instead:

Controller

↓

Spring Proxy

↓

OrderService

The proxy gets the first opportunity to execute logic before calling the actual method.


Step 3: TransactionInterceptor Starts the Transaction

The proxy delegates the work to Spring’s TransactionInterceptor.

This interceptor checks:

  • Is the method transactional?
  • Which propagation should be used?
  • Which isolation level should be used?
  • Should a new transaction be created?

If required, it asks the PlatformTransactionManager to begin a transaction.


Step 4: TransactionManager Opens a Database Transaction

Spring internally uses implementations such as:

  • DataSourceTransactionManager
  • JpaTransactionManager

The transaction manager obtains a database connection and executes:

connection.setAutoCommit(false);

This marks the beginning of the transaction.

Now all database operations will execute within the same transaction.


Step 5: Business Logic Executes

Your actual method finally runs.

@Transactional
public void placeOrder() {

    orderRepository.save(order);

    paymentRepository.save(payment);

    cartRepository.clearCart(userId);

}

All repository calls use the same database connection.


Step 6: Commit or Rollback

If everything succeeds:

connection.commit();

If an exception occurs:

connection.rollback();

Finally, the connection is returned to the connection pool.


Why Does Spring Use ThreadLocal?

One common interview question is:

How do all repository methods use the same database connection?

Spring stores the transaction resources in a ThreadLocal using TransactionSynchronizationManager.

Thread 1

↓

Connection A

---------------------

Thread 2

↓

Connection B

Every repository call made within the same thread automatically uses the same connection.


Why Does Self-Invocation Fail?

Consider this code:

@Service
public class OrderService {

    public void process() {
        saveOrder();
    }

    @Transactional
    public void saveOrder() {

    }
}

Here,

process()

↓

this.saveOrder()

The call never goes through the Spring Proxy.

Since the proxy is bypassed, Spring cannot start a transaction.

Therefore, @Transactional has no effect.

How to solve it?

Move the transactional method to another Spring bean or call it through the proxy.


Does @Transactional Work in a Monolith?

Yes.

In a monolithic application, all modules usually share the same database.

Example:

OrderService

β”‚

β”œβ”€β”€ OrderRepository

β”œβ”€β”€ PaymentRepository

└── CartRepository

Since every repository uses the same database, a single transaction can manage all operations.

This is the most common use of @Transactional.


Does @Transactional Work in Microservices?

Yesβ€”but only within a single microservice.

For example:

Order Service

β”‚

β”œβ”€β”€ OrderRepository

└── AuditRepository

Both repositories use the Order Service database.

@Transactional works perfectly here.


Can @Transactional Manage Transactions Across Multiple Microservices?

No.

Consider this architecture:

Order Service
      β”‚
      β”œβ”€β”€ Order Database
      β”‚
      └── Calls
             β”‚
             β–Ό
Payment Service
             β”‚
             └── Payment Database

Now there are two separate databases and two independent transactions.

If the payment service fails after the order is saved, Spring cannot roll back the Order Service transaction because it only controls the current application’s database transaction.

This is one of the biggest limitations of @Transactional.


How Are Distributed Transactions Handled?

Instead of relying on @Transactional, modern microservices use patterns such as:

  • Saga Pattern
  • Eventual Consistency
  • Outbox Pattern
  • Kafka or RabbitMQ for event-driven communication

Each microservice commits its own transaction independently, and failures are handled using compensation logic rather than a single database rollback.


Common Interview Questions

1. Does @Transactional use AOP?

Yes. Spring uses AOP proxies to intercept method calls and apply transaction management.


2. What proxy does Spring create?

  • JDK Dynamic Proxy (if an interface exists)
  • CGLIB Proxy (if no interface exists)

3. What class actually manages the transaction?

PlatformTransactionManager

Common implementations:

  • DataSourceTransactionManager
  • JpaTransactionManager

4. What happens if an exception occurs?

By default:

  • RuntimeException β†’ Rollback
  • Error β†’ Rollback
  • Checked Exception β†’ Commit (unless configured using rollbackFor)

5. Why doesn’t @Transactional work for self-invocation?

Because the method call bypasses the Spring proxy.


6. Can @Transactional work across multiple microservices?

No.

It only manages transactions within the current application’s database.

Distributed transactions require Saga, Eventual Consistency, or similar patterns.


Interview Answer (2-Minute Version)

“@Transactional works internally using Spring AOP and the Proxy Pattern. When Spring detects a transactional method, it creates a proxy around the bean. Whenever the method is called, the proxy intercepts the request and delegates it to TransactionInterceptor, which asks the PlatformTransactionManager to start a transaction by obtaining a database connection and disabling auto-commit. The business method then executes. If it completes successfully, Spring commits the transaction; otherwise, it rolls it back for runtime exceptions. Finally, the connection is released back to the connection pool. This works well in monolithic applications and within a single microservice, but it cannot manage transactions across multiple microservices or databases. For distributed transactions, patterns like Saga and Eventual Consistency are used.”


Key Takeaways

  • @Transactional uses Spring AOP.
  • Spring creates a Proxy Object around the bean.
  • The proxy invokes TransactionInterceptor.
  • PlatformTransactionManager starts and manages the database transaction.
  • All repository operations share the same connection through ThreadLocal.
  • Success results in Commit; failures trigger Rollback.
  • Self-invocation bypasses the proxy, so transactions are not applied.
  • @Transactional is ideal for monolithic applications and single microservices.
  • For transactions spanning multiple services or databases, use Saga, Outbox Pattern, and Eventual Consistency instead of @Transactional.