1.REQUIRED(默认)
描述:如果当前存在事务,则加入该事务;如果不存在,则创建一个新的事务。
适用场景:大多数情况下使用此选项。它是最常见的传播行为,适用于大多数业务逻辑。
示例:
@Service
public class UserService {
@Autowired
private OrderService orderService;
@Transactional(propagation = Propagation.REQUIRED)
public void createUserAndOrder() {
// 创建用户
createUser();
// 创建订单
orderService.createOrder();
}
private void createUser() {
// 用户创建逻辑
System.out.println("User created.");
}
}
@Service
public class OrderService {
@Transactional(propagation = Propagation.REQUIRED)
public void createOrder() {
// 订单创建逻辑
System.out.println("Order created.");
}
}
解释:
如果 createUserAndOrder 和 createOrder 都在同一个事务中调用,它们将共享同一个事务。
如果 createOrder 抛出异常,整个事务将回滚,包括 createUser 的操作。
2. SUPPORTS
描述:如果当前存在事务,则加入该事务;如果不存在,则以非事务方式执行。
适用场景:当方法不需要事务支持时使用,但可以容忍在事务中运行。例如,读取数据或生成报告。
示例:
@Service
public class ReportingService {
@Transactional(propagation = Propagation.SUPPORTS)
public void generateReport() {
// 生成报告逻辑
System.out.println("Report generated.");
}
}
解释:
如果当前有事务,generateReport 将加入该事务。
如果没有事务,generateReport 将以非事务方式执行。
3. MANDATORY
描述:如果当前存在事务,则加入该事务;如果不存在,则抛出异常。
适用场景:确保方法必须在一个已有的事务中执行。例如,某些验证逻辑必须在事务上下文中进行。
示例:
@Service
public class ValidationService {
@Transactional(propagation = Propagation.MANDATORY)
public void validateData() {
// 数据验证逻辑
System.out.println("Data validated.");
}
}
解释:
如果 validateData 在没有事务的情况下被调用,会抛出 IllegalTransactionStateException 异常。
这确保了验证逻辑始终在一个事务中执行。
4. REQUIRES_NEW
描述:创建一个新的事务,如果当前存在事务,则将当前事务挂起。
适用场景:需要独立于外部事务的新事务,例如日志记录或发送邮件等操作。
示例:
@Service
public class LoggingService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logActivity(String message) {
// 日志记录逻辑
System.out.println("Logged: " + message);
}
}
解释:
logActivity 总是运行在一个新的独立事务中。
即使外部事务失败,logActivity 的事务仍然可以成功提交。
5. NOT_SUPPORTED
描述:以非事务方式执行操作,如果当前存在事务,则暂停当前事务。
适用场景:当方法不应该参与任何事务时使用,例如读取配置文件等操作。
示例:
@Service
public class ConfigService {
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void readConfig() {
// 读取配置文件逻辑
System.out.println("Configuration read.");
}
}
解释:
如果当前有事务,readConfig 将暂停该事务并以非事务方式执行。
这确保了配置读取不会受到事务的影响。
6. NEVER
描述:以非事务方式执行,如果当前存在事务,则抛出异常。
适用场景:确保方法永远不会在一个事务中执行。例如,健康检查或监控操作。
示例:
@Service
public class HealthCheckService {
@Transactional(propagation = Propagation.NEVER)
public void checkHealth() {
// 健康检查逻辑
System.out.println("Health check performed.");
}
}
解释:
如果 checkHealth 在事务中被调用,会抛出 IllegalTransactionStateException 异常。
确保健康检查始终以非事务方式执行。
7. NESTED
描述:如果当前存在事务,则在嵌套事务内执行;如果不存在,则创建一个新的事务。嵌套事务可以独立提交或回滚。
适用场景:需要更细粒度的事务控制,例如部分操作失败不影响其他操作。
示例:
@Service
public class TransactionalService {
@Transactional(propagation = Propagation.REQUIRED)
public void performOperations() {
try {
// 操作1
operation1();
// 操作2,使用嵌套事务
operation2();
} catch (Exception e) {
// 操作2失败,不影响操作1
System.out.println("Operation2 failed, but Operation1 succeeded.");
}
}
@Transactional(propagation = Propagation.NESTED)
public void operation2() {
// 模拟一个条件导致操作2失败
if (true) {
throw new RuntimeException("Operation2 failed.");
}
System.out.println("Operation2 succeeded.");
}
private void operation1() {
// 操作1逻辑
System.out.println("Operation1 succeeded.");
}
}
解释:
operation2 在 performOperations 的嵌套事务中执行。
如果 operation2 失败,只有 operation2 的事务会被回滚,而 operation1 的事务不受影响。