NIUCLOUD是一款SaaS管理后台框架多应用插件+云编译。上千名开发者、服务商正在积极拥抱开发者生态。欢迎开发者们免费入驻。一起助力发展! 广告
以下是几个使用Spring事务处理订单的案例,涵盖了声明式事务和分布式事务的场景: ### 1\. 声明式事务处理订单 #### 场景描述 用户下单时,需要完成以下操作: 1. 创建订单记录。 2. 扣减库存。 3. 扣减用户余额。 如果任何一个步骤失败,整个操作需要回滚。 #### 代码实现 ```java @Service public class OrderService { @Autowired private OrderRepository orderRepository; @Autowired private InventoryService inventoryService; @Transactional( propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, timeout = 30, rollbackFor = {InsufficientStockException.class, PaymentFailedException.class} ) public void placeOrder(Order order) { inventoryService.reduceStock(order.getItems()); // 可能抛出 InsufficientStockException orderRepository.save(order); processPayment(order); // 可能抛出 PaymentFailedException } private void processPayment(Order order) { // 支付逻辑 } } ``` #### 事务说明 - 使用`@Transactional`注解声明事务,指定传播行为为`REQUIRED`,隔离级别为`READ_COMMITTED`,超时时间为30秒。 - 如果在扣减库存或支付过程中抛出异常,事务会回滚,确保订单记录、库存和用户余额的状态保持一致。 ### 2\. 分布式事务处理订单支付 #### 场景描述 跨服务的订单支付涉及订单服务、支付服务和库存服务,需要保证跨服务事务的一致性。 #### 代码实现 ```java @Service public class DistributedOrderService { @Autowired private OrderService orderService; @Autowired private PaymentService paymentService; @Autowired private InventoryService inventoryService; @GlobalTransactional(name = "createOrderTx", timeoutMills = 30000) public void createOrderWithPayment(OrderRequest request) { // 1. 创建订单(本地事务) Order order = orderService.create(request); // 2. 调用支付服务(远程事务) paymentService.process(order.getId(), order.getAmount()); // 3. 扣减库存(跨服务调用) inventoryService.deduct(order.getProductId(), order.getQuantity()); } } ``` #### 事务说明 - 使用Seata实现分布式事务管理,通过`@GlobalTransactional`注解声明全局事务。 - 如果任何一个服务(订单服务、支付服务、库存服务)失败,全局事务会回滚,确保数据一致性。 ### 3\. 声明式事务处理复杂订单逻辑 #### 场景描述 用户下单时,需要完成以下操作: 1. 验证订单信息。 2. 锁定库存。 3. 扣减用户余额。 4. 使用优惠券(如果有)。 5. 创建订单记录。 #### 代码实现 ```java @Service public class OrderServiceImpl implements OrderService { @Autowired private OrderDao orderDao; @Autowired private ProductDao productDao; @Autowired private AccountDao accountDao; @Autowired private CouponDao couponDao; @Autowired private InventoryService inventoryService; @Transactional( propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, timeout = 30, rollbackFor = {BusinessException.class, RuntimeException.class} ) @Override public OrderResult createOrder(OrderRequest request) throws BusinessException { // 1. 验证订单基本信息 validateOrderRequest(request); // 2. 锁定库存(使用REQUIRES_NEW传播行为,独立事务) inventoryService.lockInventory(request.getProductId(), request.getQuantity()); // 3. 扣减账户余额 deductAccountBalance(request.getUserId(), request.getTotalAmount()); // 4. 使用优惠券(如果有) if (request.getCouponId() != null) { useCoupon(request.getUserId(), request.getCouponId()); } // 5. 创建订单 Order order = createOrderRecord(request); // 6. 发送创建订单事件(异步,不影响主事务) sendOrderCreatedEvent(order); return convertToResult(order); } private void validateOrderRequest(OrderRequest request) throws BusinessException { // 验证逻辑... if (request.getQuantity() <= 0) { throw new BusinessException("购买数量必须大于0"); } } @Transactional(propagation = Propagation.REQUIRES_NEW) public void lockInventory(Long productId, int quantity) throws BusinessException { // 锁定库存逻辑... } private void deductAccountBalance(Long userId, BigDecimal amount) throws BusinessException { // 扣减余额逻辑... } @Transactional(propagation = Propagation.MANDATORY) public void useCoupon(Long userId, Long couponId) throws BusinessException { // 使用优惠券逻辑... } private Order createOrderRecord(OrderRequest request) { // 创建订单记录逻辑... } private void sendOrderCreatedEvent(Order order) { // 异步发送事件... } } ``` #### 事务说明 - 使用`@Transactional`注解声明事务,指定传播行为和隔离级别。 - 对于锁定库存的操作,使用`Propagation.REQUIRES_NEW`传播行为,确保其独立提交,即使主事务失败也不会影响库存锁定操作。 ### 4\. 编程式事务处理订单 #### 场景描述 使用编程式事务处理订单创建逻辑。 #### 代码实现 ```java @Service public class OrderService { @Autowired private PlatformTransactionManager transactionManager; @Autowired private OrderRepository orderRepository; public CreateOrderResult createOrder(CreateOrderRequest request) { GenericTransactionTemplate<CreateOrderRequest, CreateOrderResult> template = new GenericTransactionTemplate<>(transactionManager); return template.execute(request, new GenericTransactionTemplate.TransactionProcessor<>() { @Override public Function<CreateOrderRequest, CreateOrderResult> consume() { return req -> { // 事务内核心逻辑 Order order = new Order(); order.setUserId(req.getUserId()); order.setAmount(req.getAmount()); orderRepository.save(order); return new CreateOrderResult(order.getId(), "SUCCESS"); }; } @Override public Predicate<CreateOrderRequest> filter() { // 过滤非法金额订单 return req -> req.getAmount().compareTo(BigDecimal.ZERO) > 0; } @Override public void verify(CreateOrderRequest req) { if (req.getUserId() == null) { throw new IllegalArgumentException("User ID cannot be null"); } } @Override public void onTransactionException(Exception e) { log.error("Order creation failed in transaction: {}", request, e); } @Override public void afterCompletion() { log.info("Order processing completed for request: {}", request); } }, TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 使用独立事务 } } ``` #### 事务说明 - 使用`PlatformTransactionManager`和`GenericTransactionTemplate`实现编程式事务。 - 在事务中完成订单创建逻辑,并在异常时进行处理。 以上案例展示了Spring事务在不同场景下的应用,包括单体应用中的声明式事务、分布式事务以及编程式事务。