全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-18 8 分钟 ✍️ juanwangdev

声明式事务与编程式事务

Spring提供两种事务管理方式:声明式和编程式。

两种方式对比

特性声明式事务编程式事务
实现方式@Transactional注解TransactionTemplate或PlatformTransactionManager
代码侵入
灵活性较低较高
细粒度控制方法级别代码块级别
可读性一般
维护成本较高

声明式事务

注解方式

Java
@Service
public class OrderService {

    @Transactional
    public void createOrder(Order order) {
        orderDao.insert(order);
        inventoryService.decrease(order.getProductId());
    }

    @Transactional(readOnly = true)
    public Order getOrder(Long id) {
        return orderDao.findById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    public void batchImport(List<Order> orders) throws Exception {
        for (Order order : orders) {
            orderDao.insert(order);
        }
    }
}

XML配置方式

XML
<!-- 事务管理器 -->
<bean id="transactionManager"
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<!-- 事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="save*" propagation="REQUIRED"/>
        <tx:method name="update*" propagation="REQUIRED"/>
        <tx:method name="delete*" propagation="REQUIRED"/>
        <tx:method name="get*" read-only="true"/>
        <tx:method name="find*" read-only="true"/>
        <tx:method name="*" propagation="REQUIRED"/>
    </tx:attributes>
</tx:advice>

<!-- AOP配置 -->
<aop:config>
    <aop:advisor advice-ref="txAdvice"
                 pointcut="execution(* com.example.service.*.*(..))"/>
</aop:config>

启用事务注解

Java
@Configuration
@EnableTransactionManagement  // 启用注解事务
public class AppConfig {

    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

Spring Boot项目无需此配置,自动配置事务管理器。

编程式事务

TransactionTemplate方式(推荐)

Java
@Service
public class PaymentService {

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private AccountDao accountDao;

    // 无返回值事务
    public void transfer(Long fromId, Long toId, BigDecimal amount) {
        transactionTemplate.executeWithoutResult(status -> {
            try {
                accountDao.decrease(fromId, amount);
                accountDao.increase(toId, amount);
            } catch (Exception e) {
                status.setRollbackOnly();
                throw e;
            }
        });
    }

    // 有返回值事务
    public Long createAccount(String name, BigDecimal balance) {
        return transactionTemplate.execute(status -> {
            Account account = new Account(name, balance);
            accountDao.insert(account);
            return account.getId();
        });
    }

    // 自定义事务属性
    public void customTransaction() {
        transactionTemplate.setPropagationBehavior(
            TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        transactionTemplate.setIsolationLevel(
            TransactionDefinition.ISOLATION_READ_COMMITTED);
        transactionTemplate.setTimeout(30);

        transactionTemplate.executeWithoutResult(status -> {
            // 业务逻辑
        });
    }
}

PlatformTransactionManager方式

Java
@Service
public class ManualTxService {

    @Autowired
    private PlatformTransactionManager transactionManager;

    @Autowired
    private OrderDao orderDao;

    public void manualControl() {
        DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
        definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        definition.setTimeout(30);

        TransactionStatus status = transactionManager.getTransaction(definition);

        try {
            orderDao.insert(new Order());

            // 根据条件决定提交或回滚
            if (someCondition()) {
                transactionManager.commit(status);
            } else {
                transactionManager.rollback(status);
            }
        } catch (Exception e) {
            transactionManager.rollback(status);
            throw e;
        }
    }
}

使用场景选择

声明式事务适用场景

Java
// 场景1:常规CRUD操作
@Service
public class UserService {

    @Transactional
    public void save(User user) {
        userDao.save(user);
    }

    @Transactional(readOnly = true)
    public User findById(Long id) {
        return userDao.findById(id);
    }
}

// 场景2:标准业务流程
@Service
public class OrderService {

    @Transactional
    public void createOrder(OrderRequest request) {
        Order order = buildOrder(request);
        orderDao.insert(order);
        inventoryService.decrease(request.getProductId(), request.getQuantity());
        paymentService.charge(request.getPayment());
    }
}

编程式事务适用场景

Java
// 场景1:细粒度控制
@Service
public class ImportService {

    @Autowired
    private TransactionTemplate transactionTemplate;

    public ImportResult batchImport(List<Data> dataList) {
        int success = 0, failed = 0;

        for (Data data : dataList) {
            // 每条数据独立事务
            try {
                transactionTemplate.executeWithoutResult(status -> {
                    dataDao.insert(data);
                    relatedDao.insert(data.getRelated());
                });
                success++;
            } catch (Exception e) {
                failed++;
                // 单条失败不影响其他
            }
        }
        return new ImportResult(success, failed);
    }
}

// 场景2:条件性回滚
@Service
public class ConditionService {

    public void process(Order order) {
        transactionTemplate.executeWithoutResult(status -> {
            orderDao.insert(order);

            if (needRollback(order)) {
                status.setRollbackOnly();  // 手动回滚
                return;
            }

            notificationService.send(order);
        });
    }
}

// 场景3:嵌套事务控制
@Service
public class NestedService {

    public void nestedProcess() {
        transactionTemplate.executeWithoutResult(outer -> {
            outerDao.doSomething();

            // 内层独立事务
            TransactionTemplate innerTx = new TransactionTemplate(transactionManager);
            innerTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
            innerTx.executeWithoutResult(inner -> {
                innerDao.doSomething();
            });
        });
    }
}

混合使用

Java
@Service
public class MixedService {

    @Autowired
    private TransactionTemplate transactionTemplate;

    // 声明式事务
    @Transactional
    public void declarativeMethod() {
        // 自动事务管理
    }

    // 编程式事务
    public void programmaticMethod() {
        transactionTemplate.executeWithoutResult(status -> {
            // 手动事务控制
        });
    }

    // 在声明式事务中使用编程式事务(创建新事务)
    @Transactional
    public void mixed() {
        // 外层事务
        outerOperation();

        // 内层独立事务
        TransactionTemplate newTx = new TransactionTemplate(transactionManager);
        newTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        newTx.executeWithoutResult(status -> {
            // 独立事务,外层回滚不影响此处
            logService.saveLog();
        });
    }
}

最佳实践

场景推荐方式原因
常规业务方法声明式简洁、可读性好
批量处理部分失败编程式细粒度控制
条件性回滚编程式灵活控制
需要事务内独立事务编程式精确控制传播
团队协作项目声明式统一风格

要点总结

  • 声明式事务通过@Transactional实现,代码简洁
  • 编程式事务通过TransactionTemplate实现,控制灵活
  • 声明式适合大多数常规场景
  • 编程式适合需要细粒度控制的特殊场景
  • TransactionTemplate比直接使用PlatformTransactionManager更简洁
  • 同一类中可混合使用两种方式

📝 发现内容有误?点击此处直接编辑

← 上一篇 事务隔离级别
下一篇 → ApplicationContextAwareProcessor
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库