PlatformTransactionManager 是 Spring 编程式事务核心接口,需在 Spring 管理的 Bean 中注入使用,通过 TransactionStatus 显式控制事务开启、提交与回滚;推荐结合 TransactionTemplate 简化开发并避免常见事务失效问题。

在 Spring 中,PlatformTransactionManager 是编程式事务管理的核心接口,适用于需要精细控制事务边界(比如动态决定是否提交/回滚、嵌套逻辑判断、非 Spring 管理的资源等)的场景。它不依赖 @Transactional 注解,而是通过代码显式调用开启、提交或回滚事务。
获取并使用 PlatformTransactionManager 实例
通常由 Spring 容器自动配置(如 DataSourceTransactionManager 或 JpaTransactionManager),你只需注入即可:
// 在 Service 或任意 Spring Bean 中
@Service
public class OrderService {
@Autowired
private PlatformTransactionManager transactionManager;
<pre class="brush:php;toolbar:false;">@Autowired
private JdbcTemplate jdbcTemplate;
立即学习“Java免费学习笔记(深入)”;
注意:不能在普通 new 出来的对象中直接使用,必须是 Spring 管理的 Bean,否则 transactionManager 为 null 或事务不生效。
手动开启、提交与回滚事务
核心步骤是:创建事务定义 → 获取事务状态 → 执行业务 → 显式提交或回滚。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
示例:转账操作中,余额不足则回滚:
public void transfer(String from, String to, BigDecimal amount) {
// 1. 定义事务规则(可选,默认 PROPAGATION_REQUIRED)
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
<pre class="brush:php;toolbar:false;">// 2. 开启事务,获取事务状态
TransactionStatus status = transactionManager.getTransaction(def);
try {
// 3. 执行业务逻辑(如扣款、入账)
jdbcTemplate.update("UPDATE account SET balance = balance - ? WHERE name = ?",
amount, from);
jdbcTemplate.update("UPDATE account SET balance = balance + ? WHERE name = ?",
amount, to);
// 4. 检查业务条件:若余额可能为负,主动回滚
Integer count = jdbcTemplate.queryForObject(
"SELECT COUNT(*) FROM account WHERE name = ? AND balance >= 0",
Integer.class, from);
if (count == 0) {
throw new IllegalStateException("余额不足,事务将回滚");
}
// 5. 提交事务
transactionManager.commit(status);
} catch (Exception ex) {
// 6. 出现异常时回滚(即使没抛出,也可根据条件调用 rollback)
transactionManager.rollback(status);
throw ex;
}}
关键点:
- TransactionStatus 必须保存好,它是当前事务的唯一上下文,commit/rollback 都要传入它
- 不要在 try 块外调用
commit(),否则可能对已回滚或已完成的事务重复提交 - 回滚后不要再调用
commit(),Spring 会抛UnexpectedRollbackException - 若只是想“取消”事务而不抛异常,直接调用
rollback(status)即可
结合 TransactionTemplate 简化写法(推荐)
相比裸用 PlatformTransactionManager,TransactionTemplate 封装了模板逻辑,更简洁安全:
@Autowired
private TransactionTemplate transactionTemplate;
<p>public void transferWithTemplate(String from, String to, BigDecimal amount) {
transactionTemplate.execute(status -> {
try {
jdbcTemplate.update("UPDATE account SET balance = balance - ? WHERE name = ?",
amount, from);
jdbcTemplate.update("UPDATE account SET balance = balance + ? WHERE name = ?",
amount, to);</p><pre class="brush:php;toolbar:false;"> // 校验失败时触发回滚:抛出 RuntimeException(或其子类)
if (jdbcTemplate.queryForObject(
"SELECT balance FROM account WHERE name = ?",
BigDecimal.class, from) == null) {
throw new RuntimeException("账户不存在");
}
return null;
} catch (Exception e) {
status.setRollbackOnly(); // 显式标记仅回滚(非必须,抛异常也会回滚)
throw e;
}
});}
优势:
- 自动处理 commit/rollback,无需手动管理
TransactionStatus - 回调内抛出运行时异常默认触发回滚,语义清晰
- 支持自定义
TransactionDefinition(如只读、超时)
注意事项和常见坑
编程式事务不是万能的,容易出错的地方包括:
- 事务不生效:方法被本类其他方法直接调用(绕过代理)、事务管理器未正确配置、数据源未接入事务管理
-
嵌套事务行为不符合预期:Spring 默认不支持真正的嵌套事务(savepoint 需手动用
TransactionStatus创建) -
多线程下事务失效:
TransactionSynchronizationManager基于 ThreadLocal,子线程无法继承父事务 -
资源未关闭或连接泄漏:确保 JDBC 操作使用 Spring 封装的模板(如
JdbcTemplate),避免手动Connection.close()干扰事务管理
不复杂但容易忽略:事务边界的粒度要匹配业务语义,避免把无关操作包进同一个事务,也别让事务过长阻塞数据库。


















