Master Spring Transaction Management: ACID, Isolation Levels, and Propagation
This article explains Spring's transaction mechanism, covering its reliance on database support, ACID properties, isolation levels, propagation attributes, programmatic and declarative management styles, and the underlying AOP implementation with concrete code examples.
What Is Spring Transaction?
Spring itself does not implement transaction logic; it merely provides an abstraction over the underlying database's transaction capabilities. By combining Spring IoC and Spring AOP, developers can use declarative transactions that require no invasive code changes. When using plain JDBC, a typical transaction involves five steps: obtaining a connection, disabling auto‑commit, performing CRUD operations, committing or rolling back, and finally closing the connection. Spring handles all steps except the business logic (step 3).
1、获取连接 Connection con = DriverManager.getConnection();
2、开启事务 con.setAutoCommit(true/false);
3、执行CRUD
4、提交事务/回滚事务 con.commit() / con.rollback();
5、关闭连接 conn.close();ACID Properties
Transactions guarantee four essential properties—Atomicity, Consistency, Isolation, and Durability. Atomicity ensures that a series of actions either all succeed or have no effect. Consistency requires the database to remain in a valid state before and after the transaction. Isolation prevents concurrent transactions from interfering with each other, and Durability makes committed changes permanent.
Isolation Levels in Spring
Spring maps the standard JDBC isolation levels to five options:
DEFAULT : Uses the database's default isolation.
READ_UNCOMMITTED : Allows dirty reads; the lowest isolation.
READ_COMMITTED : Prevents dirty reads but may allow non‑repeatable reads and phantom reads.
REPEATABLE_READ : Prevents dirty and non‑repeatable reads; phantom reads may still occur.
SERIALIZABLE : Highest cost, fully prevents dirty reads, non‑repeatable reads, and phantom reads by executing transactions sequentially.
Propagation Attributes
Spring defines seven PROPAGATION_ constants that control how a transaction joins or creates a new one. The diagram in the original article illustrates each mode (e.g., REQUIRED, REQUIRES_NEW, NESTED, etc.).
Two Management Approaches
Spring supports both programmatic (code‑driven) and declarative (annotation‑driven) transaction management.
Programmatic Transaction Management
Developers can use TransactionTemplate or PlatformTransactionManager to define transaction boundaries explicitly. The community generally recommends TransactionTemplate for its callback‑style simplicity.
@Autowired
private TransactionTemplate transactionTemplate;
public void testTransaction() {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
try {
// ... business logic ...
} catch (Exception e) {
// rollback
transactionStatus.setRollbackOnly();
}
}
});
}Declarative Transaction Management
Using the @Transactional annotation (or XML configuration) lets Spring create proxies that start, commit, or roll back transactions automatically around the annotated method.
@Transactional
public void insert(String userName) {
this.jdbcTemplate.update("insert into t_user (name) values (?)", userName);
}Implementation Details (AOP)
Spring’s transaction support relies on AOP to weave transaction logic into target methods. The core interceptor is TransactionInterceptor, whose invoke() method obtains the target class, then delegates to invokeWithinTransaction. Inside, createTransactionIfNecessary builds a TransactionInfo object, binds transaction attributes to the current thread, and obtains a TransactionStatus from the configured PlatformTransactionManager.
@Override
public Object invoke(final MethodInvocation invocation) throws Throwable {
Class<?> targetClass = (invocation.getThis() != null ?
AopUtils.getTargetClass(invocation.getThis()) : null);
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}The manager’s getTransaction() method creates a new transaction when none exists, validates timeout settings, and respects the propagation behavior (e.g., REQUIRED, REQUIRES_NEW, NESTED). For a new transaction, it calls startTransaction, which ultimately invokes DataSourceTransactionManager.doBegin to set the connection to manual‑commit mode.
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {
TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
Object transaction = doGetTransaction();
if (isExistingTransaction(transaction)) {
return handleExistingTransaction(def, transaction, debugEnabled);
}
if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
}
if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException("No existing transaction found for transaction marked with propagation 'mandatory'");
} else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
SuspendedResourcesHolder suspendedResources = suspend(null);
try {
return startTransaction(def, transaction, debugEnabled, suspendedResources);
} catch (RuntimeException | Error ex) {
resume(null, suspendedResources);
throw ex;
}
} else {
// empty transaction (no actual DB transaction)
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
}
}Summary of Spring Transaction Mechanics
Spring transaction management is essentially a combination of AOP‑based method interception and the underlying database’s transaction support. When a transactional method starts, Spring decides whether to begin a new transaction (setting auto‑commit to false) or join an existing one. After the method completes, Spring either commits the transaction or rolls it back if a specified exception occurs.
Architect Chen
Sharing over a decade of architecture experience from Baidu, Alibaba, and Tencent.
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.
