Spring @Transactional
注解是一种强大的声明式事务管理工具,允许在方法级别轻松定义事务边界。以下是对 @Transactional
注解的详细说明,包括基本用法、属性说明、默认事务回滚规则以及如何处理不同类型的异常:
1. 基本用法
将 @Transactional
注解应用于服务层或业务逻辑方法上,使该方法及其内部数据库操作在一个统一的事务中执行。示例:
@Service
public class UserService {
@Transactional
public void updateUserAndAccount(User user, Account account) {
userRepository.save(user);
accountRepository.save(account);
}
}
在这个例子中,updateUserAndAccount
方法被标记为 @Transactional
,意味着更新用户信息和账户信息的操作将在同一事务中执行。如果其中任何一个操作失败(抛出未捕获的异常),整个事务将被回滚,确保数据一致性。
2. 属性说明
@Transactional
注解支持多种属性以定制事务行为:
- value 或 transactionManager: 指定事务管理器的 bean 名称,用于在有多个事务管理器时选择特定的一个。
- propagation: 设置事务传播行为,例如
PROPAGATION_REQUIRED
(默认)表示如果当前存在事务则加入该事务,否则新建一个事务。 - isolation: 设置事务隔离级别,如
ISOLATION_READ_COMMITTED
(默认)。 - timeout: 以秒为单位设置事务超时时间,超过该时间仍未提交的事务将自动回滚。
- readOnly: 标记事务是否为只读,只读事务可以提高数据库性能,但不能执行写操作。
- rollbackFor: 指定遇到哪些异常类型时应触发事务回滚。
- noRollbackFor: 指定遇到哪些异常类型时不触发事务回滚。
3. 默认事务回滚规则
- 运行时异常(
RuntimeException
及其子类):未被捕获的运行时异常(如NullPointerException
、IllegalArgumentException
等)会触发事务回滚。
@Service
public class UserService {
@Transactional
public void updateUserAndThrowRuntimeError(User user) {
userRepository.save(user);
throw new IllegalArgumentException("Invalid user data"); // 事务将回滚
}
}
- 非运行时异常(检查型异常):默认情况下,未被捕获的非运行时异常(如
SQLException
、IOException
等)不会触发事务回滚。
@Service
public class UserService {
@Transactional
public void updateUserAndThrowCheckedError(User user) throws SQLException {
userRepository.save(user);
throw new SQLException("Database error occurred"); // 事务不会回滚
}
}
4. 显式指定回滚异常
- 若要使特定的非运行时异常触发事务回滚,可以使用
@Transactional
注解的rollbackFor
属性明确指定。
@Service
public class UserService {
@Transactional(rollbackFor = SQLException.class)
public void updateUserAndThrowCheckedErrorWithConfig(User user) throws SQLException {
userRepository.save(user);
throw new SQLException("Database error occurred"); // 事务将回滚
}
}
其他注意事项
@Transactional
注解应应用于由 Spring 管理的 Bean 上的方法,确保其在 Spring 容器中被正确创建和管理。- 事务管理依赖于 Spring AOP 动态代理机制。内部方法调用(同一类中的方法相互调用)可能无法正确应用事务,建议通过接口调用或依赖注入避免此问题。
- 异常处理时,确保未被捕获且应触发回滚的异常能够向上抛出,避免在方法内部捕获并处理这些异常,导致事务不被回滚。
总结而言,Spring @Transactional
注解提供了一种简便的方式在方法级别定义事务边界,支持多种属性以定制事务行为。默认情况下,仅未被捕获的运行时异常会触发事务回滚,非运行时异常需通过 rollbackFor
属性显式指定才能触发回滚。使用时还需注意其生效范围、AOP 切面代理原理及异常处理规则。