Java事务回滚触发的典型案例
运行时异常自动回滚案例
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepository;
@Autowired
private InventoryService inventoryService;
@Transactional
public void createOrder(Order order) {
// 1. 保存订单
orderRepository.save(order);
// 2. 扣减库存 - 如果这里抛出运行时异常,订单保存也会回滚
inventoryService.deductStock(order.getProductId(), order.getQuantity());
// 3. 模拟业务异常
if (order.getAmount() > 10000) {
throw new RuntimeException("订单金额超过限制");
}
}
}
检查型异常不会自动回滚
@Service
public class PaymentService {
@Transactional
public void processPayment(Payment payment) throws Exception {
// 1. 扣款
deductFromAccount(payment.getAccountId(), payment.getAmount());
// 2. 这个检查型异常不会触发回滚!
if (payment.getAmount() > 5000) {
throw new Exception("大额支付需要审核");
}
}
// 正确做法:包装成运行时异常或指定rollbackFor
@Transactional(rollbackFor = Exception.class)
public void processPayment2(Payment payment) throws Exception {
// 扣款操作
deductFromAccount(payment.getAccountId(), payment.getAmount());
if (payment.getAmount() > 5000) {
throw new Exception("大额支付需要审核");
}
}
}
嵌套事务回滚案例
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private LogService logService;
@Transactional
public void registerUser(User user) {
// 1. 保存用户
userRepository.save(user);
// 2. 记录日志 - 事务传播行为REQUIRES_NEW
try {
logService.saveLog("用户注册: " + user.getName());
} catch (Exception e) {
// 日志失败不影响用户注册
System.out.println("日志记录失败,但用户注册成功");
}
// 3. 发送欢迎邮件
sendWelcomeEmail(user);
}
}
@Service
public class LogService {
@Autowired
private LogRepository logRepository;
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveLog(String message) {
logRepository.save(new Log(message));
// 模拟日志保存失败
if (message.contains("错误")) {
throw new RuntimeException("日志保存异常");
}
}
}
编程式事务回滚
@Service
public class AccountService {
@Autowired
private PlatformTransactionManager transactionManager;
@Autowired
private AccountRepository accountRepository;
public void transferMoney(Long fromId, Long toId, BigDecimal amount) {
// 定义事务
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
def.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);
TransactionStatus status = transactionManager.getTransaction(def);
try {
// 1. 扣款
Account fromAccount = accountRepository.findById(fromId).orElseThrow();
fromAccount.setBalance(fromAccount.getBalance().subtract(amount));
accountRepository.save(fromAccount);
// 2. 检查余额
if (fromAccount.getBalance().compareTo(BigDecimal.ZERO) < 0) {
throw new RuntimeException("余额不足");
}
// 3. 入账
Account toAccount = accountRepository.findById(toId).orElseThrow();
toAccount.setBalance(toAccount.getBalance().add(amount));
accountRepository.save(toAccount);
// 提交事务
transactionManager.commit(status);
} catch (RuntimeException e) {
// 回滚事务
transactionManager.rollback(status);
throw e;
} catch (Exception e) {
// 回滚事务
transactionManager.rollback(status);
throw new RuntimeException("转账失败", e);
}
}
}
使用TransactionAspectSupport手动回滚
@Service
public class DocumentService {
@Transactional
public void uploadDocument(Document doc) {
// 1. 保存文档
documentRepository.save(doc);
// 2. 上传到文件服务器
boolean uploadSuccess = fileService.upload(doc.getContent(), doc.getPath());
if (!uploadSuccess) {
// 手动回滚,同时保留异常信息
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
throw new RuntimeException("文件上传失败,事务回滚");
}
// 3. 更新文档状态
doc.setStatus("UPLOADED");
documentRepository.save(doc);
}
}
常见的触发回滚场景
@Service
public class BatchProcessService {
@Transactional
public void batchUpdate(List<Entity> entities) {
for (int i = 0; i < entities.size(); i++) {
Entity entity = entities.get(i);
try {
// 处理每个实体
processSingleEntity(entity);
} catch (DataIntegrityViolationException e) {
// 数据完整性违规 - 自动回滚
throw e;
} catch (OptimisticLockException e) {
// 乐观锁异常 - 自动回滚
throw e;
} catch (Exception e) {
// 处理单个失败,不影响其他
log.error("处理第{}个实体失败: {}", i, e.getMessage());
}
}
}
private void processSingleEntity(Entity entity) {
// 可能抛出各种异常
}
}
- 默认行为:只有
RuntimeException和Error及其子类会触发回滚 - 检查型异常:默认不回滚,需通过
rollbackFor指定 - 嵌套事务:
REQUIRES_NEW会暂停当前事务,独立异常不影响外层 - 手动回滚:使用
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly() - 编程式事务:通过
PlatformTransactionManager精确控制
这些案例覆盖了实际开发中最常见的事务回滚场景。

版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播