在 Spring 中,事务管理是通过 @Transactional
注解和事务管理器来实现的。下面介绍 Spring 中的事务管理
事务的四大特性(ACID)
-
原子性(Atomicity):事务中的一系列操作要么全部成功提交,要么全部失败回滚,保证数据的一致性。
-
一致性(Consistency):事务执行前后,数据库从一个一致性状态转移到另一个一致性状态,确保数据的正确性。
-
隔离性(Isolation):事务并发执行时,每个事务都应该被隔离开来,避免互相干扰,从而确保数据的完整性。
-
持久性(Durability):事务提交成功后,对数据的修改会被永久保存到数据库中,即使系统发生故障也不会丢失。
事务的传播机制
Spring 提供了七种事务传播行为,可以通过 propagation
属性来设置:
-
PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
-
PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,则以非事务方式执行。
-
PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,则抛出异常。
-
PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则将当前事务挂起。
-
PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,则将当前事务挂起。
-
PROPAGATION_NEVER:以非事务方式执行操作,如果当前存在事务,则抛出异常。
-
PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务中执行,如果当前没有事务,则创建一个新的事务。
事务注解失效的场景
事务注解可能会失效的场景包括:
- 在同一个类中的方法调用:如果在同一个类中的方法直接调用另一个带有
@Transactional
注解的方法,事务注解可能会失效。 - 异常被吞噬:如果在事务方法内部捕获了异常并未重新抛出,事务可能不会回滚。
- 异步方法:如果在异步方法上使用了
@Transactional
注解,事务可能不会生效,因为 Spring 无法拦截异步方法的调用。
示例代码
下面是一个简单的示例代码,演示了 Spring 中如何使用 @Transactional
注解来管理事务:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Service
public class MyService {
@Autowired
private MyRepository myRepository;
@Transactional(propagation = Propagation.REQUIRED)
public void performTransactionalOperation() {
// 原子性:一系列数据库操作要么全部成功提交,要么全部失败回滚
myRepository.save(entity);
myRepository.update(entity);
// 一致性:事务结束后,数据库从一个一致性状态转移到另一个一致性状态
// 隔离性:事务的隔离级别由配置决定,例如可以设置为 Isolation.READ_COMMITTED
// 持久性:成功提交的数据修改会永久保存到数据库中
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void performAnotherTransactionalOperation() {
// 在新的事务中执行操作,不受外部事务影响
}
}
在上述代码中,MyService
类中的方法使用了 @Transactional
注解来声明事务管理,通过设置 propagation
属性来定义事务的传播行为。