Unit Testing Spring Transaction Propagation: Practical Insights
This article provides a complete, runnable unit‑test suite for Spring Boot 3.x that demonstrates and verifies every transaction‑propagation behavior (REQUIRED, REQUIRES_NEW, NESTED, SUPPORTS, MANDATORY), highlights common pitfalls such as self‑calls and swallowed exceptions, and shows how to configure the environment, write the test code, and run the tests.
Version and Environment
The tests are based on Spring Boot 3.2.4 with Spring Framework 6.x and require JDK 17+ . The Maven dependencies include Spring Boot starter, AOP, Data JPA, the H2 in‑memory database, and Spring Boot Test.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.4</version>
</parent>
<dependencies>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Spring Boot AOP -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- Spring Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- H2 Database -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Spring Boot Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>Test Class and Preconditions
The main test class TransactionPropagationTest uses JUnit 5 and Spring Boot Test. Preconditions are:
Spring Boot 3.2.4 + JDK 21
H2 in‑memory database ( jdbc:h2:mem:testdb)
JPA + Hibernate auto‑create tables
Each test method rolls back by default because of @Transactional on the test class
Test Cases – Propagation Behaviors
The suite contains ten test methods that cover the five standard propagation types and four typical failure traps, plus a solution using rollbackFor:
REQUIRED : child joins parent transaction; an exception rolls back the whole transaction.
REQUIRES_NEW : child runs in an independent transaction; parent rollback does not affect child data.
NESTED : child creates a savepoint; rolling back the child restores the savepoint while the parent can still commit.
SUPPORTS : joins a transaction if one exists; otherwise runs non‑transactionally.
MANDATORY : throws IllegalTransactionStateException when no surrounding transaction is present.
Self‑call trap : a this.xxx() call bypasses the AOP proxy, so REQUIRES_NEW does not take effect.
Swallowed exception trap : catching an exception prevents Spring from marking the transaction for rollback.
Checked‑exception trap : by default only RuntimeException triggers rollback; checked exceptions do not.
Non‑public method trap : @Transactional on a non‑public method is ignored.
Solution : adding @Transactional(rollbackFor = Exception.class) forces rollback for checked exceptions.
Auxiliary Classes
Supporting source files include: SpringContainerApplication – the boot entry point with @EnableJpaRepositories.
Application YAML configuring the H2 datasource, Hibernate DDL auto‑create, and SQL logging. TxTestEntity – a simple JPA entity with id and name fields. TxTestRepository – extends JpaRepository<TxTestEntity, Integer> and provides findByName and countByName.
Service beans for each propagation type ( RequiredService, RequiresNewService, NestedService, SupportsService, MandatoryService) that perform a simple repository.save(...) and optionally throw a RuntimeException.
Parent services ( ParentWithRequiresNewService, ParentWithNestedService, ParentWithSupportsService, ParentWithMandatoryService) that invoke the child services to demonstrate nested transaction behavior. SelfCallService – illustrates the proxy‑bypass problem and the exception‑swallowing scenario.
Running the Tests
Tests can be executed via Maven: mvn test -Dtest=TransactionPropagationTest or directly from IntelliJ IDEA by right‑clicking the test class or method and selecting “Run” or “Debug”.
Reference
The code accompanies the article “Spring Transaction Propagation Full Analysis”.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
CodeSmart Hoops
A working programmer who loves coding and basketball. By day I debug code; by night I dissect tactics. I write articles to document my journey, focusing on Java, AI, Python and other programming topics, with occasional posts about basketball, English, and books. Hope it's helpful—thanks for following and support.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
