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)失效场景众多,一不小心就会造成事务失效

相关推荐
ly76898 小时前
MongoDB 事务开销实测:快照隔离下的写冲突、重试与分片事务边界
数据库·mongodb·事务·分片集群·快照隔离·写冲突
豆角焖肉9 小时前
Spring AOP 自定义注解实现系统操作日志
数据库·自定义注解·springaop·操作日志·aop 切面
鬼手点金9 小时前
opencode-rules 插件
java·开发语言·前端·人工智能·chrome·git·github
金伟API102410 小时前
不会写复杂SQL怎么办?
数据库·sql
paopaokaka_luck10 小时前
滑雪场管理系统(AI智能助手流式对话,ECharts 运营数据分析、教练、雪具与场地一体化预约,钱包支付退款、订单核销与服务评价)
java·人工智能·spring boot·网络协议·数据分析·echarts
执笔为剑10 小时前
2.1.2-1、V8R3迁移到V8R6-Oracle兼容特性
数据库
考虑考虑10 小时前
@JsonInclude注解使用
spring boot·后端·spring
Wang's Blog10 小时前
Java 项目实战: 交友项目 - Dubbo 的内部结构与一次调用的完整链路
java·dubbo
geovindu10 小时前
sql:Search-Optimized SQL Queries using mysql 9.0
android·数据库·sql·mysql·数据库开发·数据库架构
Wang's Blog11 小时前
Java 项目实战: 交友项目 - Dubbo 入门引导
java·dubbo·交友