【附录】Spring 事务管理 基础知识及应用

36 阅读12分钟

此文是 【Spring 容器详解】-> 【 ApplicationContext 做了哪些企业化的增强?】的支节点。

Spring的事务管理(Transaction Management)是ApplicationContext相对于BeanFactory的重要企业级增强功能。Spring提供了声明式和编程式两种事务管理方式,支持多种事务传播行为、隔离级别和回滚策略,为复杂的企业级应用提供了强大的事务支持。

1. BeanFactory的事务管理限制

1.1 BeanFactory的局限性

BeanFactory作为Spring的核心容器,在事务管理方面存在以下限制:

  • 无内置事务支持:BeanFactory本身不提供事务管理功能
  • 缺乏事务抽象:无法统一管理不同类型的事务
  • 无事务注解支持:不支持@Transactional等事务注解
  • 事务配置复杂:需要手动配置事务管理器和事务模板

1.2 示例代码

// BeanFactory缺乏事务支持
public class BeanFactoryTransactionExample {
    
    public static void main(String[] args) {
        // 创建BeanFactory
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        
        // BeanFactory本身不提供事务功能
        // 无法使用@Transactional注解
        // 无法自动配置事务管理器
        // 需要通过其他方式实现事务管理
        
        // 手动实现事务管理
        Connection connection = null;
        try {
            connection = getConnection();
            connection.setAutoCommit(false);
            
            // 执行业务逻辑
            createUser(connection, "John Doe");
            createUserProfile(connection, 1L);
            
            // 提交事务
            connection.commit();
            System.out.println("事务提交成功");
        } catch (Exception e) {
            // 回滚事务
            if (connection != null) {
                try {
                    connection.rollback();
                    System.out.println("事务回滚成功");
                } catch (SQLException ex) {
                    System.err.println("事务回滚失败: " + ex.getMessage());
                }
            }
            throw new RuntimeException("事务执行失败", e);
        } finally {
            // 关闭连接
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    System.err.println("关闭连接失败: " + e.getMessage());
                }
            }
        }
    }
    
    private static Connection getConnection() throws SQLException {
        // 获取数据库连接
        return DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "user", "password");
    }
    
    private static void createUser(Connection connection, String name) throws SQLException {
        // 创建用户
        String sql = "INSERT INTO users (name) VALUES (?)";
        try (PreparedStatement stmt = connection.prepareStatement(sql)) {
            stmt.setString(1, name);
            stmt.executeUpdate();
        }
    }
    
    private static void createUserProfile(Connection connection, Long userId) throws SQLException {
        // 创建用户档案
        String sql = "INSERT INTO user_profiles (user_id, created_at) VALUES (?, ?)";
        try (PreparedStatement stmt = connection.prepareStatement(sql)) {
            stmt.setLong(1, userId);
            stmt.setTimestamp(2, new Timestamp(System.currentTimeMillis()));
            stmt.executeUpdate();
        }
    }
}

2. ApplicationContext的事务管理扩展

2.1 核心注解:@EnableTransactionManagement

ApplicationContext通过@EnableTransactionManagement启用事务管理功能:

@Configuration
@EnableTransactionManagement
public class TransactionConfig {
    
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }
    
    @Bean
    public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {
        return new TransactionTemplate(transactionManager);
    }
}

2.2 事务管理器的类型

Spring支持多种事务管理器:

@Configuration
public class TransactionManagerConfig {
    
    // 1. 数据源事务管理器
    @Bean
    public DataSourceTransactionManager dataSourceTransactionManager(DataSource dataSource) {
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }
    
    // 2. JPA事务管理器
    @Bean
    public JpaTransactionManager jpaTransactionManager(EntityManagerFactory entityManagerFactory) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory);
        return transactionManager;
    }
    
    // 3. Hibernate事务管理器
    @Bean
    public HibernateTransactionManager hibernateTransactionManager(SessionFactory sessionFactory) {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(sessionFactory);
        return transactionManager;
    }
    
    // 4. JTA事务管理器
    @Bean
    public JtaTransactionManager jtaTransactionManager() {
        JtaTransactionManager transactionManager = new JtaTransactionManager();
        return transactionManager;
    }
    
    // 5. 链式事务管理器
    @Bean
    public ChainedTransactionManager chainedTransactionManager(
            DataSourceTransactionManager dataSourceTransactionManager,
            JpaTransactionManager jpaTransactionManager) {
        
        return new ChainedTransactionManager(dataSourceTransactionManager, jpaTransactionManager);
    }
}

3. 声明式事务管理

3.1 @Transactional注解详解

@Service
@Transactional
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private UserProfileRepository userProfileRepository;
    
    // 1. 基本事务
    @Transactional
    public User createUser(String name, String email) {
        User user = new User();
        user.setName(name);
        user.setEmail(email);
        user.setCreatedAt(LocalDateTime.now());
        
        User savedUser = userRepository.save(user);
        
        // 创建用户档案
        UserProfile profile = new UserProfile();
        profile.setUserId(savedUser.getId());
        profile.setCreatedAt(LocalDateTime.now());
        userProfileRepository.save(profile);
        
        return savedUser;
    }
    
    // 2. 指定传播行为
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public User createUserInNewTransaction(String name, String email) {
        // 在新事务中创建用户
        return createUser(name, email);
    }
    
    // 3. 指定隔离级别
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public User getUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }
    
    // 4. 指定超时时间
    @Transactional(timeout = 30)
    public void updateUserBatch(List<User> users) {
        for (User user : users) {
            userRepository.save(user);
        }
    }
    
    // 5. 指定回滚策略
    @Transactional(rollbackFor = {SQLException.class, DataIntegrityViolationException.class})
    public void createUserWithRollback(String name, String email) {
        User user = new User();
        user.setName(name);
        user.setEmail(email);
        userRepository.save(user);
        
        // 如果这里抛出异常,事务会回滚
        if (name == null || name.trim().isEmpty()) {
            throw new IllegalArgumentException("用户名不能为空");
        }
    }
    
    // 6. 只读事务
    @Transactional(readOnly = true)
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }
    
    // 7. 条件事务
    @Transactional(rollbackFor = Exception.class, noRollbackFor = IllegalArgumentException.class)
    public void createUserConditional(String name, String email) {
        User user = new User();
        user.setName(name);
        user.setEmail(email);
        userRepository.save(user);
        
        // IllegalArgumentException不会导致回滚
        if (email == null || !email.contains("@")) {
            throw new IllegalArgumentException("邮箱格式不正确");
        }
        
        // 其他异常会导致回滚
        if (name == null) {
            throw new RuntimeException("用户名不能为空");
        }
    }
}

3.2 事务传播行为

@Service
public class TransactionPropagationService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private OrderRepository orderRepository;
    
    // 1. REQUIRED(默认):如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务
    @Transactional(propagation = Propagation.REQUIRED)
    public void createUserAndOrder(String userName, String orderName) {
        // 创建用户
        User user = new User();
        user.setName(userName);
        userRepository.save(user);
        
        // 创建订单
        Order order = new Order();
        order.setUserId(user.getId());
        order.setName(orderName);
        orderRepository.save(order);
        
        // 如果任何操作失败,整个事务都会回滚
    }
    
    // 2. REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则挂起当前事务
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void createUserInNewTransaction(String name) {
        User user = new User();
        user.setName(name);
        userRepository.save(user);
        
        // 这个操作在独立的事务中执行
        // 即使外部事务回滚,这个操作也会提交
    }
    
    // 3. SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式执行
    @Transactional(propagation = Propagation.SUPPORTS)
    public User getUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }
    
    // 4. NOT_SUPPORTED:以非事务的方式执行,如果当前存在事务,则挂起当前事务
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void sendNotification(String message) {
        // 发送通知,不参与事务
        System.out.println("发送通知: " + message);
    }
    
    // 5. MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常
    @Transactional(propagation = Propagation.MANDATORY)
    public void updateUserInTransaction(Long id, String name) {
        User user = userRepository.findById(id).orElse(null);
        if (user != null) {
            user.setName(name);
            userRepository.save(user);
        }
        
        // 这个方法必须在事务中调用
    }
    
    // 6. NEVER:以非事务的方式执行,如果当前存在事务,则抛出异常
    @Transactional(propagation = Propagation.NEVER)
    public void logOperation(String operation) {
        // 记录操作日志,不能在事务中执行
        System.out.println("记录操作: " + operation);
    }
    
    // 7. NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来执行
    @Transactional(propagation = Propagation.NESTED)
    public void createUserProfile(Long userId) {
        UserProfile profile = new UserProfile();
        profile.setUserId(userId);
        profile.setCreatedAt(LocalDateTime.now());
        
        // 这个操作在嵌套事务中执行
        // 如果外部事务回滚,这个操作也会回滚
        // 如果这个操作失败,外部事务可以选择回滚或继续
    }
}

3.3 事务隔离级别

@Service
public class TransactionIsolationService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private AccountRepository accountRepository;
    
    // 1. READ_UNCOMMITTED:读未提交,最低隔离级别,允许脏读
    @Transactional(isolation = Isolation.READ_UNCOMMITTED)
    public User getUserWithDirtyRead(Long id) {
        // 可能读取到未提交的数据
        return userRepository.findById(id).orElse(null);
    }
    
    // 2. READ_COMMITTED:读已提交,防止脏读,但允许不可重复读
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public User getUserWithReadCommitted(Long id) {
        // 只能读取已提交的数据
        return userRepository.findById(id).orElse(null);
    }
    
    // 3. REPEATABLE_READ:可重复读,防止不可重复读,但允许幻读
    @Transactional(isolation = Isolation.REPEATABLE_READ)
    public List<User> getUsersWithRepeatableRead() {
        // 在事务期间,多次读取会得到相同的结果
        return userRepository.findAll();
    }
    
    // 4. SERIALIZABLE:串行化,最高隔离级别,防止所有并发问题
    @Transactional(isolation = Isolation.SERIALIZABLE)
    public void transferMoney(Long fromAccountId, Long toAccountId, BigDecimal amount) {
        Account fromAccount = accountRepository.findById(fromAccountId).orElse(null);
        Account toAccount = accountRepository.findById(toAccountId).orElse(null);
        
        if (fromAccount != null && toAccount != null) {
            if (fromAccount.getBalance().compareTo(amount) >= 0) {
                fromAccount.setBalance(fromAccount.getBalance().subtract(amount));
                toAccount.setBalance(toAccount.getBalance().add(amount));
                
                accountRepository.save(fromAccount);
                accountRepository.save(toAccount);
            } else {
                throw new InsufficientFundsException("余额不足");
            }
        }
    }
    
    // 5. 默认隔离级别(通常是READ_COMMITTED)
    @Transactional
    public User getUserWithDefaultIsolation(Long id) {
        return userRepository.findById(id).orElse(null);
    }
}

4. 编程式事务管理

4.1 TransactionTemplate使用

@Service
public class TransactionTemplateService {
    
    @Autowired
    private TransactionTemplate transactionTemplate;
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private OrderRepository orderRepository;
    
    // 1. 基本使用
    public User createUserWithTemplate(String name, String email) {
        return transactionTemplate.execute(status -> {
            try {
                User user = new User();
                user.setName(name);
                user.setEmail(email);
                user.setCreatedAt(LocalDateTime.now());
                
                User savedUser = userRepository.save(user);
                
                // 创建用户档案
                UserProfile profile = new UserProfile();
                profile.setUserId(savedUser.getId());
                profile.setCreatedAt(LocalDateTime.now());
                
                return savedUser;
            } catch (Exception e) {
                status.setRollbackOnly();
                throw e;
            }
        });
    }
    
    // 2. 指定事务属性
    public User createUserWithCustomTransaction(String name, String email) {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        def.setTimeout(30);
        def.setReadOnly(false);
        
        return transactionTemplate.execute(def, status -> {
            User user = new User();
            user.setName(name);
            user.setEmail(email);
            user.setCreatedAt(LocalDateTime.now());
            
            return userRepository.save(user);
        });
    }
    
    // 3. 异常处理
    public User createUserWithExceptionHandling(String name, String email) {
        return transactionTemplate.execute(status -> {
            try {
                User user = new User();
                user.setName(name);
                user.setEmail(email);
                user.setCreatedAt(LocalDateTime.now());
                
                User savedUser = userRepository.save(user);
                
                // 模拟异常
                if (name == null || name.trim().isEmpty()) {
                    throw new IllegalArgumentException("用户名不能为空");
                }
                
                return savedUser;
            } catch (IllegalArgumentException e) {
                // 特定异常不回滚
                status.setRollbackOnly();
                throw e;
            } catch (Exception e) {
                // 其他异常回滚
                status.setRollbackOnly();
                throw e;
            }
        });
    }
    
    // 4. 嵌套事务
    public void createUserAndOrder(String userName, String orderName) {
        transactionTemplate.execute(status -> {
            // 创建用户
            User user = createUserInNestedTransaction(userName);
            
            // 创建订单
            Order order = new Order();
            order.setUserId(user.getId());
            order.setName(orderName);
            orderRepository.save(order);
            
            return null;
        });
    }
    
    private User createUserInNestedTransaction(String name) {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
        
        return transactionTemplate.execute(def, status -> {
            User user = new User();
            user.setName(name);
            user.setCreatedAt(LocalDateTime.now());
            return userRepository.save(user);
        });
    }
}

4.2 PlatformTransactionManager使用

@Service
public class PlatformTransactionManagerService {
    
    @Autowired
    private PlatformTransactionManager transactionManager;
    
    @Autowired
    private UserRepository userRepository;
    
    // 1. 基本使用
    public User createUserWithManager(String name, String email) {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        
        TransactionStatus status = transactionManager.getTransaction(def);
        
        try {
            User user = new User();
            user.setName(name);
            user.setEmail(email);
            user.setCreatedAt(LocalDateTime.now());
            
            User savedUser = userRepository.save(user);
            
            // 提交事务
            transactionManager.commit(status);
            return savedUser;
        } catch (Exception e) {
            // 回滚事务
            transactionManager.rollback(status);
            throw e;
        }
    }
    
    // 2. 复杂事务管理
    public void complexTransactionOperation() {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        def.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
        def.setTimeout(60);
        
        TransactionStatus status = transactionManager.getTransaction(def);
        
        try {
            // 第一步操作
            performFirstOperation();
            
            // 检查是否需要继续
            if (shouldContinue()) {
                // 第二步操作
                performSecondOperation();
            }
            
            // 提交事务
            transactionManager.commit(status);
        } catch (Exception e) {
            // 回滚事务
            transactionManager.rollback(status);
            throw e;
        }
    }
    
    private void performFirstOperation() {
        // 执行第一步操作
        System.out.println("执行第一步操作");
    }
    
    private boolean shouldContinue() {
        // 判断是否继续执行
        return true;
    }
    
    private void performSecondOperation() {
        // 执行第二步操作
        System.out.println("执行第二步操作");
    }
}

5. 事务事件和监听器

5.1 事务事件监听

@Component
public class TransactionEventListener {
    
    private static final Logger logger = LoggerFactory.getLogger(TransactionEventListener.class);
    
    // 1. 事务提交后事件
    @EventListener
    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    public void handleAfterCommit(TransactionEvent event) {
        logger.info("事务提交后处理事件: {}", event.getMessage());
        
        // 在事务提交后执行的操作
        // 例如:发送通知、更新缓存等
        sendNotification(event.getMessage());
        updateCache(event.getData());
    }
    
    // 2. 事务回滚后事件
    @EventListener
    @TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
    public void handleAfterRollback(TransactionEvent event) {
        logger.info("事务回滚后处理事件: {}", event.getMessage());
        
        // 在事务回滚后执行的操作
        // 例如:记录失败日志、发送告警等
        logFailure(event.getMessage());
        sendAlert(event.getMessage());
    }
    
    // 3. 事务完成事件(无论提交还是回滚)
    @EventListener
    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)
    public void handleAfterCompletion(TransactionEvent event) {
        logger.info("事务完成后处理事件: {}", event.getMessage());
        
        // 在事务完成后执行的操作
        // 例如:清理资源、更新统计信息等
        cleanupResources();
        updateStatistics();
    }
    
    private void sendNotification(String message) {
        // 发送通知
        System.out.println("发送通知: " + message);
    }
    
    private void updateCache(Object data) {
        // 更新缓存
        System.out.println("更新缓存: " + data);
    }
    
    private void logFailure(String message) {
        // 记录失败日志
        System.err.println("记录失败: " + message);
    }
    
    private void sendAlert(String message) {
        // 发送告警
        System.err.println("发送告警: " + message);
    }
    
    private void cleanupResources() {
        // 清理资源
        System.out.println("清理资源");
    }
    
    private void updateStatistics() {
        // 更新统计信息
        System.out.println("更新统计信息");
    }
}

// 事务事件类
public class TransactionEvent {
    private final String message;
    private final Object data;
    private final LocalDateTime timestamp;
    
    public TransactionEvent(String message, Object data) {
        this.message = message;
        this.data = data;
        this.timestamp = LocalDateTime.now();
    }
    
    // getter方法
    public String getMessage() { return message; }
    public Object getData() { return data; }
    public LocalDateTime getTimestamp() { return timestamp; }
}

5.2 事务同步

@Service
public class TransactionSynchronizationService {
    
    @Autowired
    private UserRepository userRepository;
    
    // 1. 事务同步
    @Transactional
    public void createUserWithSynchronization(String name, String email) {
        // 注册事务同步
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
            @Override
            public void beforeCommit(boolean readOnly) {
                System.out.println("事务提交前执行");
            }
            
            @Override
            public void beforeCompletion() {
                System.out.println("事务完成前执行");
            }
            
            @Override
            public void afterCommit() {
                System.out.println("事务提交后执行");
                // 在这里可以安全地执行事务提交后的操作
                sendNotification(name, email);
            }
            
            @Override
            public void afterCompletion(int status) {
                System.out.println("事务完成后执行,状态: " + status);
                // 在这里可以执行清理操作
                cleanupResources();
            }
        });
        
        // 执行业务逻辑
        User user = new User();
        user.setName(name);
        user.setEmail(email);
        user.setCreatedAt(LocalDateTime.now());
        userRepository.save(user);
    }
    
    // 2. 资源绑定
    @Transactional
    public void createUserWithResourceBinding(String name, String email) {
        // 绑定资源到当前事务
        String resourceKey = "userCreation";
        Object resource = new Object();
        TransactionSynchronizationManager.bindResource(resourceKey, resource);
        
        try {
            // 执行业务逻辑
            User user = new User();
            user.setName(name);
            user.setEmail(email);
            user.setCreatedAt(LocalDateTime.now());
            userRepository.save(user);
            
            // 获取绑定的资源
            Object boundResource = TransactionSynchronizationManager.getResource(resourceKey);
            System.out.println("绑定的资源: " + boundResource);
        } finally {
            // 解绑资源
            TransactionSynchronizationManager.unbindResource(resourceKey);
        }
    }
    
    private void sendNotification(String name, String email) {
        // 发送通知
        System.out.println("发送用户创建通知: " + name + ", " + email);
    }
    
    private void cleanupResources() {
        // 清理资源
        System.out.println("清理资源");
    }
}

6. 分布式事务管理

6.1 JTA事务管理

@Configuration
public class JtaTransactionConfig {
    
    @Bean
    public JtaTransactionManager jtaTransactionManager() {
        JtaTransactionManager transactionManager = new JtaTransactionManager();
        
        // 配置JTA事务管理器
        transactionManager.setTransactionManagerName("java:/TransactionManager");
        transactionManager.setUserTransactionName("java:jboss/UserTransaction");
        
        return transactionManager;
    }
    
    @Bean
    public AtomikosDataSourceBean dataSource1() {
        AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
        dataSource.setUniqueResourceName("dataSource1");
        dataSource.setXaDataSourceClassName("com.mysql.cj.jdbc.MysqlXADataSource");
        
        Properties props = new Properties();
        props.setProperty("url", "jdbc:mysql://localhost:3306/db1");
        props.setProperty("user", "user1");
        props.setProperty("password", "password1");
        dataSource.setXaProperties(props);
        
        return dataSource;
    }
    
    @Bean
    public AtomikosDataSourceBean dataSource2() {
        AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
        dataSource.setUniqueResourceName("dataSource2");
        dataSource.setXaDataSourceClassName("com.mysql.cj.jdbc.MysqlXADataSource");
        
        Properties props = new Properties();
        props.setProperty("url", "jdbc:mysql://localhost:3306/db2");
        props.setProperty("user", "user2");
        props.setProperty("password", "password2");
        dataSource.setXaProperties(props);
        
        return dataSource;
    }
}

@Service
public class DistributedTransactionService {
    
    @Autowired
    private JdbcTemplate jdbcTemplate1;
    
    @Autowired
    private JdbcTemplate jdbcTemplate2;
    
    // 分布式事务操作
    @Transactional
    public void performDistributedOperation() {
        // 在第一个数据源上执行操作
        jdbcTemplate1.execute("INSERT INTO users (name, email) VALUES (?, ?)", 
            "User1", "user1@example.com");
        
        // 在第二个数据源上执行操作
        jdbcTemplate2.execute("INSERT INTO orders (user_id, amount) VALUES (?, ?)", 
            1L, 100.0);
        
        // 如果任何操作失败,整个分布式事务都会回滚
    }
}

6.2 链式事务管理器

@Configuration
public class ChainedTransactionConfig {
    
    @Bean
    public ChainedTransactionManager chainedTransactionManager(
            DataSourceTransactionManager dataSourceTransactionManager,
            JpaTransactionManager jpaTransactionManager) {
        
        return new ChainedTransactionManager(dataSourceTransactionManager, jpaTransactionManager);
    }
}

@Service
public class ChainedTransactionService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private OrderRepository orderRepository;
    
    // 链式事务操作
    @Transactional
    public void performChainedOperation() {
        // 在JPA事务中创建用户
        User user = new User();
        user.setName("John Doe");
        user.setEmail("john@example.com");
        userRepository.save(user);
        
        // 在JDBC事务中创建订单
        jdbcTemplate.execute("INSERT INTO orders (user_id, amount) VALUES (?, ?)", 
            user.getId(), 200.0);
        
        // 如果任何操作失败,所有事务都会回滚
    }
}

7. 事务最佳实践

7.1 事务设计原则

@Service
public class TransactionDesignService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private OrderRepository orderRepository;
    
    // 1. 事务边界要合理
    @Transactional
    public void createUserAndOrder(String userName, String orderName) {
        // 创建用户和订单是业务上相关的操作,应该在一个事务中
        User user = createUser(userName);
        createOrder(user.getId(), orderName);
    }
    
    // 2. 避免长事务
    @Transactional
    public void processLargeBatch(List<String> userNames) {
        // 分批处理,避免长事务
        int batchSize = 100;
        for (int i = 0; i < userNames.size(); i += batchSize) {
            int endIndex = Math.min(i + batchSize, userNames.size());
            List<String> batch = userNames.subList(i, endIndex);
            processBatch(batch);
        }
    }
    
    // 3. 合理使用事务传播行为
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void logOperation(String operation) {
        // 日志记录使用独立事务,避免影响主业务事务
        System.out.println("记录操作: " + operation);
    }
    
    // 4. 异常处理要明确
    @Transactional(rollbackFor = {SQLException.class, DataIntegrityViolationException.class})
    public void createUserWithClearRollback(String name, String email) {
        try {
            User user = new User();
            user.setName(name);
            user.setEmail(email);
            userRepository.save(user);
        } catch (SQLException e) {
            // 明确指定回滚
            throw new RuntimeException("数据库操作失败", e);
        }
    }
    
    private User createUser(String name) {
        User user = new User();
        user.setName(name);
        user.setCreatedAt(LocalDateTime.now());
        return userRepository.save(user);
    }
    
    private void createOrder(Long userId, String orderName) {
        Order order = new Order();
        order.setUserId(userId);
        order.setName(orderName);
        order.setCreatedAt(LocalDateTime.now());
        orderRepository.save(order);
    }
    
    private void processBatch(List<String> userNames) {
        for (String name : userNames) {
            createUser(name);
        }
    }
}

7.2 事务性能优化

@Service
public class TransactionPerformanceService {
    
    @Autowired
    private UserRepository userRepository;
    
    // 1. 使用只读事务
    @Transactional(readOnly = true)
    public List<User> getAllUsers() {
        // 只读操作使用只读事务,提高性能
        return userRepository.findAll();
    }
    
    // 2. 合理设置超时时间
    @Transactional(timeout = 10)
    public void quickOperation() {
        // 快速操作设置较短的超时时间
        System.out.println("执行快速操作");
    }
    
    // 3. 批量操作优化
    @Transactional
    public void batchInsertUsers(List<User> users) {
        // 使用批量插入提高性能
        userRepository.saveAll(users);
    }
    
    // 4. 避免在事务中执行耗时操作
    @Transactional
    public void createUserWithAsyncNotification(String name, String email) {
        // 创建用户
        User user = new User();
        user.setName(name);
        user.setEmail(email);
        userRepository.save(user);
        
        // 异步发送通知,避免阻塞事务
        CompletableFuture.runAsync(() -> {
            sendNotification(name, email);
        });
    }
    
    private void sendNotification(String name, String email) {
        // 发送通知的耗时操作
        try {
            Thread.sleep(1000);
            System.out.println("发送通知: " + name + ", " + email);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

7.3 事务监控和调试

@Component
public class TransactionMonitor {
    
    private static final Logger logger = LoggerFactory.getLogger(TransactionMonitor.class);
    
    // 1. 事务开始监控
    @EventListener
    @TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT)
    public void monitorTransactionStart(TransactionEvent event) {
        logger.info("事务开始: {}", event.getMessage());
        
        // 记录事务开始时间
        TransactionSynchronizationManager.bindResource("startTime", System.currentTimeMillis());
    }
    
    // 2. 事务提交监控
    @EventListener
    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    public void monitorTransactionCommit(TransactionEvent event) {
        logger.info("事务提交: {}", event.getMessage());
        
        // 计算事务执行时间
        Long startTime = (Long) TransactionSynchronizationManager.getResource("startTime");
        if (startTime != null) {
            long duration = System.currentTimeMillis() - startTime;
            logger.info("事务执行时间: {}ms", duration);
            
            // 记录性能指标
            recordPerformanceMetrics(duration);
        }
    }
    
    // 3. 事务回滚监控
    @EventListener
    @TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
    public void monitorTransactionRollback(TransactionEvent event) {
        logger.warn("事务回滚: {}", event.getMessage());
        
        // 记录回滚原因
        recordRollbackReason(event.getMessage());
    }
    
    // 4. 事务统计信息
    private final AtomicLong totalTransactions = new AtomicLong(0);
    private final AtomicLong committedTransactions = new AtomicLong(0);
    private final AtomicLong rolledBackTransactions = new AtomicLong(0);
    
    public Map<String, Long> getTransactionStats() {
        Map<String, Long> stats = new HashMap<>();
        stats.put("total", totalTransactions.get());
        stats.put("committed", committedTransactions.get());
        stats.put("rolledBack", rolledBackTransactions.get());
        return stats;
    }
    
    private void recordPerformanceMetrics(long duration) {
        // 记录性能指标
        if (duration > 1000) {
            logger.warn("长事务警告: {}ms", duration);
        }
    }
    
    private void recordRollbackReason(String reason) {
        // 记录回滚原因
        logger.error("事务回滚原因: {}", reason);
    }
}

总结

ApplicationContext在事务管理方面相比BeanFactory提供了以下重要扩展,其核心特性如下:

  1. 事务传播行为:REQUIRED、REQUIRES_NEW、SUPPORTS、NOT_SUPPORTED、MANDATORY、NEVER、NESTED
  2. 事务隔离级别:READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ、SERIALIZABLE
  3. 事务超时设置:控制事务执行的最大时间
  4. 回滚策略:指定哪些异常会导致事务回滚
  5. 只读事务:优化只读操作的性能