Kubernate

Design Pattern # Bridge Design Pattern Using "PlatformTransactionManager"

 Let’s map the Bridge Design Pattern directly into Spring Boot’s PlatformTransactionManager world. This is a natural fit because Spring already abstracts transaction handling across JDBC, JPA, Hibernate, and even distributed systems.


🌉 Bridge Pattern with PlatformTransactionManager

1. Core Idea

  • Abstraction (BusinessService): Your domain logic (e.g., PaymentService, OrderService).
  • Implementor (PlatformTransactionManager): Spring’s transaction abstraction.
  • Concrete Implementors: DataSourceTransactionManager, JpaTransactionManager, HibernateTransactionManager.
  • Bridge: Business services depend on the abstraction (PlatformTransactionManager), not on a specific implementation.

2. Example Code

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

// Abstraction
abstract class BusinessService {
    protected PlatformTransactionManager txManager;

    public BusinessService(PlatformTransactionManager txManager) {
        this.txManager = txManager;
    }

    public abstract void performOperation();
}

// Refined Abstraction
@Service
class PaymentService extends BusinessService {

    @Autowired
    public PaymentService(PlatformTransactionManager txManager) {
        super(txManager);
    }

    @Override
    public void performOperation() {
        TransactionDefinition def = new DefaultTransactionDefinition();
        TransactionStatus status = txManager.getTransaction(def);

        try {
            // Business logic
            System.out.println("Executing payment logic...");
            // e.g., save to DB, call external service

            txManager.commit(status);
        } catch (Exception e) {
            txManager.rollback(status);
        }
    }
}

3. Configuration Example

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;

import javax.sql.DataSource;
import javax.persistence.EntityManagerFactory;

@Configuration
public class TransactionConfig {

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName("org.postgresql.Driver");
        ds.setUrl("jdbc:postgresql://localhost:5432/mydb");
        ds.setUsername("user");
        ds.setPassword("password");
        return ds;
    }

    // Choose JDBC or JPA transaction manager
    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
        return new JpaTransactionManager(emf);
        // return new DataSourceTransactionManager(dataSource());
    }
}

4. How This Is Bridge

  • Abstraction: BusinessService (domain logic).
  • Implementor: PlatformTransactionManager.
  • Concrete Implementors: JpaTransactionManager, DataSourceTransactionManager.
  • Bridge: PaymentService composes PlatformTransactionManager and delegates transaction handling.

This way, you can swap transaction strategies without touching your service logic.


5. Real-World Usage

  • In microservices, you could extend this to plug in a distributed transaction manager (like Saga or XA).
  • In multi-database systems, you can configure multiple PlatformTransactionManager beans and inject the right one per service.


No comments:

Post a Comment

Spring Boot - Bean LifeCycle

 Here is a clear, step-by-step lifecycle of a Spring Boot application , explained in a simple + interview-ready way. 🔄 Spring Boot Applica...

Kubernate