Transaction Management - up1/course-springboot-2024 GitHub Wiki

Transaction Management in Spring Boot

  • Declarative
  • Programatic

Enable logs of database

File application.properties

spring.jpa.show-sql=true
logging.level.org.hibernate.engine.transaction.internal.TransactionImpl=DEBUG

Declarative transaction management

  • Enable transaction manager with @EnableTransactionManagement
@SpringBootApplication
@EnableTransactionManagement
public class Application {
  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}
  • User Transaction annotation
@Transactional
public class UserService {
   
    public User getUser(String id) {
       // Call database
        
    }    
    public User saveUser(User user) {
       // Call database
    }

Transaction per method

public class UserService {
    @Transactional
    public User getUser(String id) {
       // Call database
        
    }
}

Programatic transaction management

Problem ?

@Transactional 
public void completeOrder(OrderRequest request) { 
    generateOrder(request); // Call database
    generateInvoice(request); // Call database
    paymentApi(request); // Call external API
    savePaymentInfo(request); // Call database
    createSubscription(request) // Call database
    sendInvoiceEmail() // Call external API
}

Use TransactionTemplate

@Autowired private TransactionTemplate template;
public void completeOrder(OrderRequest request) { 
   template.execute(
    status -> {
       generateOrder(request); // Call database
       generateInvoice(request); // Call database       
       return request;
    });
   
    paymentApi(request); // Call external API
    template.execute(
     status -> {
       savePaymentInfo(request); // Call database
       createSubscription(request) // Call database       
       return request;
     });    
    
    sendInvoiceEmail() // Call external API
}

Config beans

@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
	return new DataSourceTransactionManager(dataSource);
}

@Bean
public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {
	return new TransactionTemplate(transactionManager);
}