声明式事务管理是Spring提供的一种事务管理机制,它允许开发者通过声明的方式,而不是通过编程的方式,来管理事务的边界和行为。在声明式事务管理中,你可以通过注解或XML配置来指定方法或类上的事务属性和行为。
在Spring中,声明式事务管理主要是借助@Transactional
注解来实现的,它可以放在类级别或方法级别。当在一个类上声明@Transactional
时,该类中的所有公共方法都将被视为事务性操作。若特定方法需要不同的事务属性,可以在该方法上单独声明@Transactional
来覆盖类级别的设置。
如何工作?
Spring的声明式事务管理背后是基于AOP(面向切面编程)。当你将@Transactional
注解到一个方法或类上时,Spring将为该方法或类创建一个代理,所有的调用都将通过这个代理。代理负责以下事务相关工作:
- 创建和管理事务上下文
- 根据设定的规则(如传播行为和隔离级别)开启新事务或加入现有事务
- 处理方法执行过程中抛出的异常,确定事务是提交还是回滚
- 根据正常执行或异常完成,提交或回滚事务
使用@Transactional
的特性:
- 传播行为:如
PROPAGATION_REQUIRED
(如果当前没有事务就新建一个,如果已经存在事务,则加入到当前事务中)。 - 隔离级别:如
ISOLATION_DEFAULT
(使用底层数据库的默认隔离级别)。 - 超时设置:定义了一个事务的超时时间。
- 只读标示:指示事务是否为只读。只读事务可以进行一些优化来提高性能。
- 回滚规则:定义了那些异常必须触发事务回滚。
示例代码:
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class MyService {@Transactional(readOnly = true)public Object readData() {// Access database and return some data// This is a read-only transaction}@Transactional(rollbackFor = Exception.class)public void updateData(SomeEntity entity) {// Update the entity in database// This transaction will rollback if any exception occurs}
}
在上面的例子中,readData
方法使用了一个只读事务,而updateData
方法则指定了任何异常都会导致事务回滚。
优点
- 简单易用:仅需通过注解或配置即可管理事务,不需要深入到事务API中。
- 代码清晰:将事务信息从业务逻辑中分离,代码更清晰、易懂。
- 一致性:提供一致的事务管理方法,预防了人为错误。
- 拦截器支持:因为基于AOP,可以很容易地为事务添加额外操作,如日志记录、性能监测等。
注意点
@Transactional
应该应用在公共方法上。在非公共方法上使用@Transactional
或在调用同一类中的另一方法(自调用)可能不会触发事务处理,因为代理无法拦截这些操作。- 事务的实际开启是在代理对象的方法被调用时发生的,所以如果没有正确使用代理对象(例如创建了对象的新实例),则声明式事务管理不会生效。