在 Spring 框架中,事务是通过对应的 AOP 模块进行实现的。Spring AOP 模块为事务提供了面向切面编程的支持,它使用代理模式为方法调用添加了事务管理逻辑。
Spring 支持声明式事务管理和编程式事务管理两种方式,其中声明式事务管理通过配置元数据,而编程式事务管理则通过 API 进行管理。
在 Spring 中,声明式事务管理是基于切面的实现,通过使用 AspectJ AOP 框架来管理事务。事务切面通常是通过实现 TransactionAspectSupport 类来完成的。该类实现了 AspectJ 框架中的 Advice 接口,并且拥有 around 方法。通过 around 方法,TransactionAspectSupport 类能够在方法调用的前后执行事务管理的相关逻辑。
在声明式事务管理中,Spring 提供了 TransactionInterceptor 类来实现事务切面。TransactionInterceptor 实现了 MethodInterceptor 接口,并且它使用
TransactionAttributeSource 接口来确定事务属性。
TransactionAttributeSource 接口定义了如何获取和解析事务元数据的方法。Spring 提供了多种
TransactionAttributeSource 的实现,如
AnnotationTransactionAttributeSource 和
NameMatchTransactionAttributeSource。
除了 TransactionInterceptor 类之外,Spring 还提供了
TransactionProxyFactoryBean 类。
TransactionProxyFactoryBean 类是一个 FactoryBean,它用于为一个特定的目标对象生成一个事务代理对象。该代理对象使用事务拦截器包装目标对象,并将事务拦截器与目标对象绑定在一起。
具体来说,Spring通过将事务管理相关的代码织入到应用程序中,来实现事务管理的功能。这个过程包括以下几个步骤:
- 定义一个切面(Aspect),该切面表示事务管理的功能,比如在方法执行前启动事务,在方法执行后提交或回滚事务等等。
- 使用AOP代理技术将这个切面织入到应用程序中。具体来说,Spring使用代理工厂(ProxyFactory)来创建一个代理对象,该代理对象在运行时将切面织入到目标对象的方法调用中。
- 在应用程序中使用事务注解或编程式的方式来声明事务。在使用注解的情况下,Spring会扫描应用程序中带有事务注解的方法,然后为这些方法创建代理对象,并将事务管理的相关代码织入到代理对象中。在编程式的方式下,开发者需要手动获取事务管理器,并在代码中使用事务模板(TransactionTemplate)来管理事务。
- 根据事务的隔离级别、传播行为、超时时间等参数来控制事务的行为。在Spring中,事务管理器(TransactionManager)可以根据这些参数来创建和管理事务。
Spring中定义了七种事务传播行为,包括:
- REQUIRED(默认):如果当前存在事务,则加入该事务,否则新建一个事务。
- SUPPORTS:如果当前存在事务,则加入该事务,否则不使用事务。
- MANDATORY:必须在一个已有的事务中执行,否则抛出异常。
- REQUIRES_NEW:新建一个事务,并在该事务中执行。如果当前存在事务,则将当前事务挂起。
- NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,则将当前事务挂起。
- NEVER:以非事务方式执行操作,如果当前存在事务,则抛出异常。
- NESTED:如果当前存在事务,则在嵌套事务中执行。如果当前没有事务,则新建一个事务。
总的来说,Spring 的事务实现基于 AOP 技术,利用代理模式为方法调用添加了事务管理逻辑。Spring 提供了声明式事务管理和编程式事务管理两种方式。其中,声明式事务管理是基于切面实现的,通过 TransactionInterceptor 类来实现事务切面。同时,Spring 也提供了多种
TransactionAttributeSource 的实现,如
AnnotationTransactionAttributeSource 和
NameMatchTransactionAttributeSource。通过这些技术,Spring 实现了一个强大而灵活的事务管理框架,可以满足不同应用场景下的事务管理需求。
代码示例:
@Service
public class MyService {
@Autowired
private MyDao myDao;
@Transactional(propagation = Propagation.REQUIRED)
public void doSomething() {
// ...
myDao.update();
doAnotherThing();
// ...
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void doAnotherThing() {
// ...
}
}
在上述代码中,MyService类中定义了两个事务方法,doSomething()和doAnotherThing()。其中,doSomething()方法的事务传播行为为REQUIRED,doAnotherThing()方法的事务传播行为为REQUIRES_NEW。
假设当前线程中没有任何事务,调用doSomething()方法时,Spring将创建一个新的事务,并在该事务中执行myDao.update()方法。接着,Spring将调用doAnotherThing()方法,在该方法中创建了一个新的事务,并在该事务中执行相关操作。在doAnotherThing()方法执行完成后,Spring会将该事务提交或回滚,并将控制权交还给doSomething()方法。
最后,Spring将提交或回滚doSomething()方法的事务,并将控制权交还给调用方。如果在执行过程中发生了异常,Spring将回滚整个事务。
您会用了吗?