@Transactional 注解是 Spring 框架中用于声明式事务管理的核心注解。它可以应用于类或方法,用于指定事务的属性,例如传播行为、隔离级别、超时时间、只读标志等。下面详细解释 @Transactional 注解的工作原理:
1. 启用事务管理:
- XML 配置: 使用
<tx:annotation-driven/>元素。 - JavaConfig: 使用
@EnableTransactionManagement注解。 - SpringBoot: 自动启用,无需额外配置(除非需要自定义)。
2. @Transactional 注解的属性:
@Transactional 注解提供了多个属性,用于配置事务的特性:
value/transactionManager: 指定事务管理器的 Bean 名称。如果只有一个事务管理器,可以省略。propagation: 指定事务的传播行为(Propagation),默认为REQUIRED。REQUIRED:如果当前存在事务,则加入该事务;如果不存在事务,则创建一个新的事务。SUPPORTS:如果当前存在事务,则加入该事务;如果不存在事务,则以非事务方式执行。MANDATORY:如果当前存在事务,则加入该事务;如果不存在事务,则抛出异常。REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则挂起当前事务。NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,则挂起当前事务。NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。NESTED:如果当前存在事务,则在嵌套事务中执行;如果不存在事务,则行为类似于REQUIRED。
isolation: 指定事务的隔离级别(Isolation),默认为DEFAULT(使用数据库的默认隔离级别)。DEFAULT:使用数据库的默认隔离级别。READ_UNCOMMITTED:读未提交,可能出现脏读、不可重复读、幻读。READ_COMMITTED:读已提交,可以避免脏读,但可能出现不可重复读、幻读。REPEATABLE_READ:可重复读,可以避免脏读、不可重复读,但可能出现幻读。SERIALIZABLE:串行化,可以避免脏读、不可重复读、幻读,但并发性能最低。
timeout: 指定事务的超时时间(秒),默认为 -1(不超时)。readOnly: 指定事务是否为只读事务,默认为false。只读事务可以提高性能(例如,数据库可以进行优化)。rollbackFor: 指定哪些异常会触发事务回滚,默认为RuntimeException和Error。可以指定多个异常类。noRollbackFor: 指定哪些异常不会触发事务回滚。可以指定多个异常类。
3. @Transactional 的工作原理:
Spring 使用 AOP(面向切面编程)来实现声明式事务管理。@Transactional 注解本质上是 AOP 的一个切点(Pointcut)。
- 创建代理对象: 当 Spring 容器创建带有
@Transactional注解的 Bean 时,会为该 Bean 创建一个代理对象(使用 JDK 动态代理或 CGLIB 动态代理)。 - 拦截方法调用: 当客户端调用代理对象的方法时,代理对象会拦截方法调用。
- 事务管理:
- 获取事务管理器: 代理对象会根据
@Transactional注解的配置,获取相应的事务管理器(PlatformTransactionManager)。 - 开启事务: 事务管理器会根据
@Transactional注解的属性(传播行为、隔离级别、超时时间等),开启一个新的事务或加入一个已存在的事务。 - 执行业务逻辑: 代理对象调用目标对象的真实方法,执行业务逻辑。
- 提交或回滚事务:
- 如果业务逻辑执行成功,事务管理器会提交事务。
- 如果业务逻辑抛出异常,事务管理器会根据
@Transactional注解的rollbackFor和noRollbackFor属性,决定是否回滚事务。默认情况下,RuntimeException和Error会触发回滚,而Exception不会。
- 获取事务管理器: 代理对象会根据
- 返回结果: 代理对象将目标方法的返回值(如果有)返回给客户端。
4. 关键类和接口:
@Transactional: Spring 提供的注解,用于声明事务。TransactionInterceptor: 实现了 AOP 的MethodInterceptor接口,负责事务的开启、提交、回滚等操作。PlatformTransactionManager: Spring 提供的事务管理器接口,用于管理事务。常见的实现类有:DataSourceTransactionManager:用于管理 JDBC 事务。HibernateTransactionManager:用于管理 Hibernate 事务。JpaTransactionManager:用于管理 JPA 事务。JtaTransactionManager:用于管理 JTA 事务。
TransactionDefinition: 定义了事务的属性(传播行为、隔离级别、超时时间、只读标志等)。TransactionStatus: 代表当前事务的状态(是否是新事务、是否已完成、是否已回滚等)。
5. 示例:
@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserDao userDao;@Override@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, timeout = 30, readOnly = false)public void createUser(User user) {// ... 执行数据库操作 ...userDao.insert(user);// ... 其他操作 ...}
}
总结:
@Transactional 注解通过 AOP 实现了声明式事务管理。Spring 会为带有 @Transactional 注解的 Bean 创建代理对象,代理对象会拦截方法调用,并根据注解的属性配置事务。Spring 通过 TransactionInterceptor 和 PlatformTransactionManager 等组件来管理事务的生命周期。理解 @Transactional 注解的工作原理,有助于我们更好地使用 Spring 框架进行事务管理,并避免常见的事务问题。
