在 Java 开发中,事务管理是确保数据一致性和完整性的关键机制,无论是金融交易、订单处理还是数据同步,合理的事务控制都能避免因系统异常导致的数据错误,本文将详细介绍 Java 中开启事务的多种方式,包括 JDBC 事务、Spring 事务管理以及 Java EE 容器事务,帮助开发者根据实际场景选择合适的方案。

JDBC 原生事务管理
JDBC(Java Database Connectivity)作为 Java 操作数据库的基础 API,提供了原生的事务管理机制,通过 Connection 对象可以手动控制事务的开启、提交和回滚。
开启事务
在 JDBC 中,默认情况下,每个 SQL 语句都在一个独立的事务中自动提交(auto-commit 为 true),要开启手动事务,需先关闭自动提交模式:
Connection connection = dataSource.getConnection(); connection.setAutoCommit(false); // 开启事务
提交与回滚事务
在执行多个 SQL 操作后,根据业务逻辑决定提交或回滚事务:
try {
// 执行 SQL 操作(如增删改)
PreparedStatement stmt1 = connection.prepareStatement("UPDATE account SET balance = balance - 100 WHERE id = 1");
stmt1.executeUpdate();
PreparedStatement stmt2 = connection.prepareStatement("UPDATE account SET balance = balance + 100 WHERE id = 2");
stmt2.executeUpdate();
connection.commit(); // 提交事务
} catch (SQLException e) {
connection.rollback(); // 发生异常时回滚事务
e.printStackTrace();
} finally {
connection.setAutoCommit(true); // 恢复自动提交模式
connection.close(); // 关闭连接
}
注意事项
- 资源管理:确保 Connection、Statement 等资源在 finally 块中关闭,避免泄漏。
- 异常处理:捕获 SQLException 并执行回滚,保证事务原子性。
- 事务隔离级别:可通过
connection.setTransactionIsolation()设置隔离级别,如 READ_COMMITTED、SERIALIZABLE 等。
Spring 框架事务管理
Spring 框架通过声明式和编程式两种方式简化了事务管理,是 Java 企业级开发中最常用的事务管理方案。
声明式事务管理
声明式事务基于 AOP(面向切面编程)实现,通过注解或 XML 配置管理事务,无需侵入业务代码。

(1)基于注解的事务管理
在 Spring 配置类中启用事务注解:
@Configuration
@EnableTransactionManagement
public class TxConfig {
@Bean
public DataSource dataSource() {
// 配置数据源
}
}
在服务类或方法上使用 @Transactional 注解:
@Service
public class AccountService {
@Autowired
private JdbcTemplate jdbcTemplate;
@Transactional // 方法级别事务
public void transferMoney(int fromId, int toId, int amount) {
jdbcTemplate.update("UPDATE account SET balance = balance - ? WHERE id = ?", amount, fromId);
jdbcTemplate.update("UPDATE account SET balance = balance + ? WHERE id = ?", amount, toId);
}
}
关键参数说明:
propagation:事务传播行为,如REQUIRED(默认,支持当前事务,否则新建事务)、REQUIRES_NEW(新建事务,挂起当前事务)。isolation:事务隔离级别,如DEFAULT(使用数据库默认级别)、READ_COMMITTED。rollbackFor:指定触发回滚的异常类,如@Transactional(rollbackFor = Exception.class)。
(2)基于 XML 的事务管理
在 Spring XML 配置文件中定义事务管理器和切面:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<aop:config>
<aop:pointcut id="serviceMethod" expression="execution(* com.example.service.*.*(..))"/>
<aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice"/>
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="transfer*" propagation="REQUIRED" isolation="DEFAULT"/>
</tx:attributes>
</tx:advice>
编程式事务管理
编程式事务通过 TransactionTemplate 或 PlatformTransactionManager 手动控制事务,适用于需要灵活事务逻辑的场景:

@Service
public class AccountService {
@Autowired
private PlatformTransactionManager transactionManager;
public void transferMoney(int fromId, int toId, int amount) {
TransactionDefinition def = new DefaultTransactionDefinition();
TransactionStatus status = transactionManager.getTransaction(def);
try {
jdbcTemplate.update("UPDATE account SET balance = balance - ? WHERE id = ?", amount, fromId);
jdbcTemplate.update("UPDATE account SET balance = balance + ? WHERE id = ?", amount, toId);
transactionManager.commit(status);
} catch (Exception e) {
transactionManager.rollback(status);
throw e;
}
}
}
Java EE 容器事务管理
在 Java EE(如 Jakarta EE)环境中,容器管理事务(CMT)通过 EJB(Enterprise JavaBeans)或 Jakarta EE 规范注解实现,无需手动控制事务。
使用 EJB 事务管理
在 EJB 组件中,通过 @TransactionAttribute 注解声明事务属性:
@Stateless
public class AccountServiceBean {
@PersistenceContext
private EntityManager em;
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void transferMoney(int fromId, int toId, int amount) {
Account fromAccount = em.find(Account.class, fromId);
Account toAccount = em.find(Account.class, toId);
fromAccount.setBalance(fromAccount.getBalance() - amount);
toAccount.setBalance(toAccount.getBalance() + amount);
em.merge(fromAccount);
em.merge(toAccount);
}
}
使用 Jakarta EE 注解
在 Jakarta EE 8+ 中,可通过 @Transactional 注解(需引入 Jakarta Transactions API):
@jakarta.transaction.Transactional
public class AccountService {
@PersistenceContext
private EntityManager em;
public void transferMoney(int fromId, int toId, int amount) {
// 业务逻辑
}
}
事务管理的最佳实践
- 明确事务边界:事务应尽量短小,避免包含耗时操作(如远程调用、文件 IO)。
- 选择合适的传播行为:根据业务场景设置事务传播规则,避免嵌套事务导致的问题。
- 异常处理:确保 RuntimeException 或指定异常触发回滚,检查异常(如 IOException)默认不回滚。
- 隔离级别与性能:在高并发场景下,合理选择隔离级别(如 READ_COMMITTED 平衡一致性与性能)。
- 避免长事务:长事务会增加锁持有时间,降低系统吞吐量,必要时考虑拆分事务。
Java 中开启事务的方式多样,从 JDBC 原生管理到 Spring 声明式/编程式事务,再到 Java EE 容器事务,开发者可根据项目需求和技术栈选择合适的方案,Spring 框架的声明式事务因其非侵入性和便捷性成为主流选择,而 JDBC 原生事务适用于简单场景或无框架依赖的项目,合理的事务管理是构建高可靠 Java 应用的基石,需结合业务场景和技术细节谨慎设计。


















