springboot事务管理几种方式

在Spring Boot中手动管理数据库事务主要有以下几种方式:

1. 编程式事务管理

1.1 使用 TransactionTemplate

复制代码
@Service
public class UserService {
    
    @Autowired
    private TransactionTemplate transactionTemplate;
    
    @Autowired
    private UserRepository userRepository;
    
    public void createUserWithTransaction() {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                try {
                    // 执行业务操作
                    User user1 = new User("张三", "zhangsan@example.com");
                    userRepository.save(user1);
                    
                    User user2 = new User("李四", "lisi@example.com");
                    userRepository.save(user2);
                    
                    // 如果需要回滚
                    // status.setRollbackOnly();
                    
                } catch (Exception e) {
                    status.setRollbackOnly();
                    throw e;
                }
            }
        });
    }
    
    // 使用lambda表达式(推荐)
    public void createUserWithTransactionLambda() {
        transactionTemplate.execute(status -> {
            try {
                User user1 = new User("张三", "zhangsan@example.com");
                userRepository.save(user1);
                
                User user2 = new User("李四", "lisi@example.com");
                userRepository.save(user2);
                
                return null;
            } catch (Exception e) {
                status.setRollbackOnly();
                throw e;
            }
        });
    }
}

1.2 使用 PlatformTransactionManager

复制代码
@Service
public class OrderService {
    
    @Autowired
    private PlatformTransactionManager transactionManager;
    
    @Autowired
    private OrderRepository orderRepository;
    
    public void createOrderWithTransaction() {
        // 定义事务属性
        DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
        definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        definition.setTimeout(30); // 30秒超时
        definition.setReadOnly(false);
        
        // 开启事务
        TransactionStatus status = transactionManager.getTransaction(definition);
        
        try {
            // 执行业务操作
            Order order = new Order();
            order.setOrderNo("ORD2023001");
            order.setAmount(new BigDecimal("100.00"));
            orderRepository.save(order);
            
            // 提交事务
            transactionManager.commit(status);
        } catch (Exception e) {
            // 回滚事务
            transactionManager.rollback(status);
            throw e;
        }
    }
}

2. 声明式事务管理(推荐)

2.1 使用 @Transactional 注解

复制代码
@Service
@Transactional // 类级别的事务配置
public class ProductService {
    
    @Autowired
    private ProductRepository productRepository;
    
    @Autowired
    private InventoryRepository inventoryRepository;
    
    // 方法级别的事务配置(会覆盖类级别的配置)
    @Transactional(
        propagation = Propagation.REQUIRED,
        isolation = Isolation.READ_COMMITTED,
        timeout = 30,
        readOnly = false,
        rollbackFor = Exception.class, // 所有异常都回滚
        noRollbackFor = BusinessException.class // 业务异常不回滚
    )
    public void createProduct(ProductDTO dto) {
        // 保存商品信息
        Product product = convertToEntity(dto);
        productRepository.save(product);
        
        // 初始化库存
        Inventory inventory = new Inventory();
        inventory.setProductId(product.getId());
        inventory.setStock(dto.getInitialStock());
        inventoryRepository.save(inventory);
        
        // 如果抛出RuntimeException,事务会自动回滚
        // 如果抛出Exception,需要配置rollbackFor才会回滚
    }
    
    // 只读事务
    @Transactional(readOnly = true)
    public Product getProductDetail(Long id) {
        return productRepository.findById(id).orElse(null);
    }
    
    // 嵌套事务
    @Transactional(propagation = Propagation.NESTED)
    public void updateProductStock(Long productId, Integer quantity) {
        // ...
    }
}

2.2 事务传播行为示例

复制代码
@Service
public class ComplexService {
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private OrderService orderService;
    
    @Transactional
    public void createOrderWithUser(Long userId, OrderDTO orderDTO) {
        // REQUIRED(默认):如果当前没有事务,就新建一个事务
        userService.validateUser(userId);
        
        // REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起
        orderService.createOrder(orderDTO);
        
        // NESTED:嵌套事务,如果当前存在事务,则在嵌套事务内执行
        // 嵌套事务是外部事务的子事务
    }
}

3. 配置事务管理器

3.1 单数据源配置

复制代码
@Configuration
@EnableTransactionManagement // 启用注解驱动的事务管理
public class TransactionConfig {
    
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

3.2 多数据源事务配置

复制代码
@Configuration
@EnableTransactionManagement
public class MultiDataSourceTransactionConfig {
    
    @Primary
    @Bean(name = "primaryTransactionManager")
    public PlatformTransactionManager primaryTransactionManager(
            @Qualifier("primaryDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
    
    @Bean(name = "secondaryTransactionManager")
    public PlatformTransactionManager secondaryTransactionManager(
            @Qualifier("secondaryDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

// 使用指定的事务管理器
@Service
public class MultiDataSourceService {
    
    @Transactional("primaryTransactionManager")
    public void primaryOperation() {
        // 使用主数据源的事务
    }
    
    @Transactional("secondaryTransactionManager")
    public void secondaryOperation() {
        // 使用次数据源的事务
    }
}

4. 事务监听器

复制代码
@Component
public class TransactionEventListener {
    
    // 事务提交后执行
    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    public void handleAfterCommit(SomeEvent event) {
        // 发送消息、记录日志等
    }
    
    // 事务回滚后执行
    @TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
    public void handleAfterRollback(SomeEvent event) {
        // 补偿操作
    }
}

@Service
public class EventPublisherService {
    
    @Autowired
    private ApplicationEventPublisher eventPublisher;
    
    @Transactional
    public void doBusiness() {
        // 业务操作
        
        // 发布事件
        eventPublisher.publishEvent(new SomeEvent(this, data));
        
        // 事务提交后,监听器会自动执行
    }
}

5. 事务最佳实践

  1. 保持事务简短:尽量减少事务中的业务逻辑

  2. 避免在事务中进行远程调用:网络延迟会增加事务持有时间

  3. 合理设置事务隔离级别:根据业务需求选择合适级别

  4. 使用只读事务优化查询@Transactional(readOnly = true)

  5. 明确指定回滚异常@Transactional(rollbackFor = Exception.class)

  6. 避免在循环中开启事务:考虑批量操作

6. 常见问题解决

6.1 事务失效场景

复制代码
@Service
public class TransactionIssueService {
    
    // 问题1:在同一个类内部调用,@Transactional不会生效
    public void methodA() {
        methodB(); // @Transactional不会生效
    }
    
    @Transactional
    public void methodB() {
        // ...
    }
    
    // 解决方案:自注入
    @Autowired
    private TransactionIssueService self;
    
    public void methodA2() {
        self.methodB(); // 通过代理调用,事务生效
    }
}

6.2 手动回滚部分操作

复制代码
@Service
public class PartialRollbackService {
    
    @Autowired
    private TransactionTemplate transactionTemplate;
    
    @Transactional
    public void complexOperation() {
        // 操作1:必须执行
        saveLog();
        
        try {
            // 操作2:可能需要回滚
            transactionTemplate.execute(status -> {
                try {
                    riskyOperation();
                    return null;
                } catch (Exception e) {
                    status.setRollbackOnly();
                    return null;
                }
            });
        } catch (Exception e) {
            // 只回滚riskyOperation,saveLog()已提交
            log.error("Risky operation failed, but log saved", e);
        }
    }
}

根据具体业务场景选择合适的事务管理方式:

  • 简单场景 :使用 @Transactional 注解

  • 复杂事务控制:使用编程式事务

  • 需要精细控制 :使用 PlatformTransactionManager

  • 批量操作 :考虑使用 TransactionTemplate

相关推荐
布局呆星2 小时前
SQLite数据库的介绍与使用
数据库·python
2401_838472512 小时前
用Python和Twilio构建短信通知系统
jvm·数据库·python
石头wang2 小时前
oracle jdbc 依赖以及对dbeaver的性能影响,如何选择oracle驱动, oracle jdbc 驱动
数据库·oracle
weixin_452159552 小时前
如何从Python初学者进阶为专家?
jvm·数据库·python
2301_790300962 小时前
用Python读取和处理NASA公开API数据
jvm·数据库·python
万象.3 小时前
redis持久化:AOF和RDB
数据库·redis·缓存
tod1133 小时前
力扣高频 SQL 50 题阶段总结(四)
开发语言·数据库·sql·算法·leetcode
!chen3 小时前
Redis快速实现布隆过滤器
数据库·redis·缓存
2301_790300964 小时前
数据分析与科学计算
jvm·数据库·python