Spring编程式事务(本地事务)

使用 TransactionTemplate等类和 API 手动管理事务,控制事务的新建、提交、回滚等过程

方式一:使用 TransactionTemplate(推荐方式)

java 复制代码
@Service
public class OrderService {
    private final TransactionTemplate transactionTemplate;
    private final OrderRepository orderRepository;
    private final InventoryRepository inventoryRepository;

    public OrderService(PlatformTransactionManager txManager,
                       OrderRepository orderRepository,
                       InventoryRepository inventoryRepository) {
        this.transactionTemplate = new TransactionTemplate(txManager);
        this.orderRepository = orderRepository;
        this.inventoryRepository = inventoryRepository;
    }

    public void createOrder(Order order) {
        transactionTemplate.execute(status -> {
            try {
                // 操作1: 保存订单
                orderRepository.save(order);
                
                // 操作2: 扣减库存
                inventoryRepository.deductStock(order.getProductId(), order.getQuantity());
                
                return "SUCCESS";
            } catch (Exception e) {
                status.setRollbackOnly(); // 标记回滚
                throw new RuntimeException("Transaction rolled back", e);
            }
        });
    }
}

方式二:使用 PlatformTransactionManager(精细控制)

java 复制代码
@Service
public class PaymentService {
    private final PlatformTransactionManager txManager;
    private final PaymentRepository paymentRepository;

    public PaymentService(PlatformTransactionManager txManager, PaymentRepository paymentRepository) {
        this.txManager = txManager;
        this.paymentRepository = paymentRepository;
    }

    public void processPayment(Payment payment) {
        // 定义事务属性(传播行为、隔离级别)
        DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
        definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        
        TransactionStatus status = txManager.getTransaction(definition);
        
        try {
            // 业务操作
            paymentRepository.save(payment);
            
            // 模拟外部服务调用(若失败需回滚)
            if (!externalPaymentGateway.charge(payment)) {
                throw new RuntimeException("Payment failed");
            }
            
            txManager.commit(status);
        } catch (Exception e) {
            txManager.rollback(status);
            throw e;
        }
    }
}

为什么不建议用声明式事务?

1)粒度不可控,最低是方法级别,容易造成大事务

2)使用不当,可能造成事务回滚不完全造成业务故障,如方法中调用了第三方接口,接口调用不能回滚

3)失效场景众多,一不小心就会造成事务失效

相关推荐
L.EscaRC7 分钟前
Spring IOC核心原理与运用
java·spring·ioc
摇滚侠20 分钟前
2025最新 SpringCloud 教程,Nacos-总结,笔记19
java·笔记·spring cloud
在逃热干面24 分钟前
(笔记)获取终端输出保存到文件
java·笔记·spring
爱笑的眼睛1125 分钟前
深入理解MongoDB PyMongo API:从基础到高级实战
java·人工智能·python·ai
笃行客从不躺平34 分钟前
遇到大SQL怎么处理
java·开发语言·数据库·sql
q***876041 分钟前
Spring Boot 整合 Keycloak
java·spring boot·后端
Billow_lamb42 分钟前
Spring Boot2.x.x全局拦截器
java·spring boot·后端
上不如老下不如小1 小时前
2025年第七届全国高校计算机能力挑战赛初赛 Java组 编程题汇总
java·计算机能力挑战赛
逻极1 小时前
Redis Queue (RQ) 核心原理:轻量任务队列的设计与实践(一句话讲透核心本质)
数据库·redis·bootstrap
泉城老铁1 小时前
Springboot对接mqtt
java·spring boot·后端