一,概念
Spring事务的原理主要基于AOP(面向切面编程)和事务抽象:
-
AOP支持:Spring使用AOP在方法执行前后织入事务管理逻辑。事务管理是通过围绕业务方法执行的代理实现的。
-
声明式事务管理:通过
@Transactional
注解或XML配置声明方法或类需要事务管理。Spring根据这些声明自动应用事务。 -
事务管理器:Spring通过
PlatformTransactionManager
接口与底层事务管理API(如JDBC、JPA)交互。 -
事务传播行为:支持不同的事务传播行为,如REQUIRED、REQUIRES_NEW等,决定事务如何在方法间传播。
-
事务隔离级别:支持设置不同的事务隔离级别,如READ_COMMITTED、SERIALIZABLE等,控制事务的可见性。
-
资源管理:自动管理事务资源(如数据库连接),在事务结束时提交或回滚事务。
Spring的事务管理旨在提供一种一致的编程模型,适用于不同的事务管理API和环境。
二,编程式和声明式事务的区别
特征 | 声明式事务 | 编程式事务 |
---|---|---|
实现方式 | 使用注解或XML配置实现 | 使用API(如TransactionTemplate)手动管理事务 |
代码侵入性 | 低,不需要修改业务代码 | 高,需要在业务代码中显式管理事务 |
管理复杂性 | 简单,事务管理由Spring容器自动完成 | 复杂,需要手动编码实现事务的开始、提交和回滚 |
灵活性 | 较低,适用于大多数标准场景 | 高,适用于需要精细控制事务的场景 |
易于阅读和维护 | 高,业务逻辑与事务控制分离 | 较低,事务控制代码与业务逻辑混杂 |
声明式事务通常是首选,因为它简单且减少了代码侵入性,而编程式事务在需要更细粒度控制时使用。
三 ,事务失效场景
Spring事务可能失效的几种情况包括:
-
非public方法上使用@Transactional:事务只能应用于公共方法。
-
自调用问题:在同一个类中一个方法直接调用另一个有@Transactional的方法,事务不会生效。
-
异常处理不当:如果只捕获异常而不重新抛出,事务无法感知到异常,因此不会回滚。
-
数据库不支持事务:使用不支持事务的数据库。
-
事务方法未通过代理调用:如直接调用事务方法,绕过了Spring代理。
-
错误的事务传播行为配置:如果配置了不合适的传播行为,可能导致事务不按预期工作。
-
事务隔离级别不当:不合适的事务隔离级别可能导致事务不一致。