https://cdn.nlark.com/yuque/0/2021/jpeg/576791/1612635261044-b7c91854-ab15-4adc-848b-a8f64d626f14.jpeg

Spring 管理事务的⽅式有⼏种?

  1. 编程式事务,在代码中硬编码。(不推荐使⽤)
  2. 声明式事务,在配置⽂件中配置(推荐使⽤)

声明式事务⼜分为两种:

  1. 基于XML的声明式事务
  2. 基于注解的声明式事务

在 Spring 框架中,事务管理是通过 Spring 的声明式事务管理和编程式事务管理来实现的。下面分别介绍这两种方式:

声明式事务管理

声明式事务管理是 Spring 中最常用的方式,它通过注解或 XML 配置来管理事务。

  1. 使用注解

    使用注解来声明事务非常简单,只需在需要事务管理的方法或类上加上 @Transactional 注解。

    步骤:

    示例:

    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    @Service
    public class MyService {
    
        @Transactional
        public void myTransactionalMethod() {
            // 事务性操作
        }
    }
    
    

    配置类:

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.transaction.PlatformTransactionManager;
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    import org.springframework.transaction.annotation.TransactionManagementConfigurer;
    
    @Configuration
    @EnableTransactionManagement
    public class AppConfig implements TransactionManagementConfigurer {
    
        @Bean
        public PlatformTransactionManager txManager() {
            return new DataSourceTransactionManager(dataSource());
        }
    
        @Override
        public PlatformTransactionManager annotationDrivenTransactionManager() {
            return txManager();
        }
    
        // 配置 DataSource 的方法
        @Bean
        public DataSource dataSource() {
            // 配置数据源
        }
    }
    
    
  2. 使用 XML 配置

    你也可以通过 XML 配置来启用事务管理。

    XML 配置示例:

    <beans xmlns="<http://www.springframework.org/schema/beans>"
           xmlns:xsi="<http://www.w3.org/2001/XMLSchema-instance>"
           xmlns:tx="<http://www.springframework.org/schema/tx>"
           xsi:schemaLocation="<http://www.springframework.org/schema/beans>
                               <http://www.springframework.org/schema/beans/spring-beans.xsd>
                               <http://www.springframework.org/schema/tx>
                               <http://www.springframework.org/schema/tx/spring-tx.xsd>">
    
        <tx:annotation-driven transaction-manager="transactionManager"/>
    
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
        </bean>
    
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
            <property name="username" value="root"/>
            <property name="password" value="password"/>
        </bean>
    
    </beans>
    
    

编程式事务管理

编程式事务管理提供了更细粒度的控制,但代码会更复杂。

  1. 使用 TransactionTemplate

    示例:

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.PlatformTransactionManager;
    import org.springframework.transaction.support.TransactionCallbackWithoutResult;
    import org.springframework.transaction.support.TransactionTemplate;
    
    @Service
    public class MyService {
    
        private final TransactionTemplate transactionTemplate;
        private final JdbcTemplate jdbcTemplate;
    
        @Autowired
        public MyService(PlatformTransactionManager transactionManager, JdbcTemplate jdbcTemplate) {
            this.transactionTemplate = new TransactionTemplate(transactionManager);
            this.jdbcTemplate = jdbcTemplate;
        }
    
        public void myTransactionalMethod() {
            transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                @Override
                protected void doInTransactionWithoutResult(TransactionStatus status) {
                    try {
                        // 事务性操作
                        jdbcTemplate.update("INSERT INTO my_table (name) VALUES (?)", "name");
                    } catch (Exception ex) {
                        status.setRollbackOnly();
                    }
                }
            });
        }
    }