当前位置: 首页 > news >正文

Spring是如何管理事务的

在 Spring 中,事务管理是通过 PlatformTransactionManager 接口实现的。Spring 提供了两种方式来管理事务:声明式事务管理和编程式事务管理。

1. 声明式事务管理

Spring 推荐使用声明式事务管理,通过 AOP(面向切面编程)来控制事务的边界。声明式事务的核心是 @Transactional 注解,它可以应用于类或方法级别,表示方法执行时需要支持事务。

基本步骤:
  1. 配置数据源:首先,配置数据源和事务管理器。
  2. 使用 @Transactional 注解:在方法或类上使用 @Transactional 注解,Spring 会自动为其创建事务。
示例代码:

假设我们有一个简单的服务 UserService,需要在 addUser 方法中添加事务管理。

1. 配置 Spring 事务管理器(XML 配置)
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource">
    <!-- 配置数据源 -->
</bean>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<bean id="transactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="transactionManager"/>
    <property name="target" ref="userService"/>
</bean>
2. 定义服务类(使用 @Transactional 注解)
import org.springframework.transaction.annotation.Transactional;

public class UserService {

    @Transactional
    public void addUser(User user) {
        // 假设我们在这里进行数据库操作
        userDao.save(user);
        // 如果存在错误,会回滚事务
    }

    @Transactional
    public void updateUser(User user) {
        // 更新用户
        userDao.update(user);
    }
}
3. 配置 @EnableTransactionManagement(Java 配置)

如果使用 Java 配置方式,可以通过 @EnableTransactionManagement 启用 Spring 的事务管理功能。

@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = "com.example")
public class AppConfig {

    @Bean
    public DataSource dataSource() {
        // 配置数据源
    }

    //事务管理器 
    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }
}

2. 编程式事务管理

编程式事务管理通过直接调用 PlatformTransactionManager 接口来实现事务的开始、提交和回滚。这种方式相对灵活,但不如声明式事务简洁。

示例代码:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

public class UserService {

    @Autowired
    private PlatformTransactionManager transactionManager;

    @Autowired
    private UserDao userDao;

    public void addUser(User user) {
        // 开始事务
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus status = transactionManager.getTransaction(def);

        try {
            // 执行数据库操作
            userDao.save(user);
            // 提交事务
            transactionManager.commit(status);
        } catch (Exception e) {
            // 回滚事务
            transactionManager.rollback(status);
            throw new RuntimeException("Error occurred while adding user", e);
        }
    }
}

3. 事务的传播行为(Propagation)

Spring 提供了多种事务传播行为,决定了事务在方法调用时如何与外部事务互动。常见的传播行为有:

  • PROPAGATION_REQUIRED:如果当前存在事务,加入该事务;如果当前没有事务,则创建一个新的事务。
  • PROPAGATION_SUPPORTS:如果当前存在事务,加入该事务;如果当前没有事务,则以非事务方式执行。
  • PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
  • PROPAGATION_REQUIRES_NEW:创建一个新的事务,并暂停当前事务。
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateUser(User user) {
    userDao.update(user);
}

4. 事务的隔离级别(Isolation)

事务的隔离级别定义了事务之间的可见性和锁的策略。常见的隔离级别有:

  • ISOLATION_READ_UNCOMMITTED:允许读取未提交的数据(最低的隔离级别,容易产生脏读)。
  • ISOLATION_READ_COMMITTED:只允许读取已提交的数据(防止脏读)。
  • ISOLATION_REPEATABLE_READ:确保在事务内读取的数据一致(防止不可重复读)。
  • ISOLATION_SERIALIZABLE:完全串行化的隔离级别,最强的隔离级别(会导致较低的并发性)。
@Transactional(isolation = Isolation.SERIALIZABLE)
public void updateUser(User user) {
    userDao.update(user);
}

5. 事务的回滚规则(Rollback)

在 Spring 中,事务默认只会对运行时异常(RuntimeException)和错误(Error)进行回滚。如果你希望对其他类型的异常进行回滚,可以在 @Transactional 注解中指定 rollbackFor 属性。

@Transactional(rollbackFor = Exception.class)
public void addUser(User user) throws Exception {
    // 如果抛出 Exception 类型的异常,也会回滚事务
    userDao.save(user);
}

总结:

Spring 的事务管理机制主要通过声明式事务管理和编程式事务管理两种方式实现:

  • 声明式事务使用 @Transactional 注解,通过 AOP 实现事务的管理,简洁易用。
  • 编程式事务通过直接操作 PlatformTransactionManager 来实现事务的开始、提交和回滚,更加灵活,但代码较为冗长。

在 Spring 中,事务的管理包括传播行为、隔离级别和回滚规则等内容,可以根据需求灵活配置。

相关文章:

  • Blender-MCP服务源码2-依赖分析
  • 汽车感性负载-智能高边钳位能量计算
  • LeetCode 3110.字符串的分数:模拟(注意一个小细节)
  • 《基于机器学习(xgboost)的人体卡路里消耗预测系统》开题报告
  • phpstudy+phpstorm+xdebug【学习笔记】
  • PreparedStatement:Java 数据库操作的安全与高效之道
  • 找工作、创业的思考和出路
  • 基于CSV构建轻量级数据库:SQL与Excel操作的双模实践
  • 【快速入门】MyBatis
  • 《灵珠觉醒:从零到算法金仙的C++修炼》卷三·天劫试炼(43)阴阳镜照连通 - 岛屿数量(DFS、BFS)
  • 使用CLINE来实现智能家居控制系统
  • c#Winform也可以跨平台了GTK框架GTKSystem.Windows.Forms
  • Centos7使用docker搭建redis集群
  • leetcode 42. 接雨水
  • AD画板学习
  • [JAVASE] Collection集合的遍历
  • MySQL常用函数详解及SQL代码示例
  • Vue 的 v-if 和 v-else-if 如何使用?
  • 信奥赛CSP-J复赛集训(模拟算法专题)(16):P6386 [COCI 2007/2008 #4] VAUVAU
  • DeepSeek本地部署 (Windows+Ollama+Docker Desktop+ RAGFlow)
  • 《克莱默夫妇》导演罗伯特·本顿去世,终年92岁
  • 王毅会见巴西外长维埃拉、总统首席特别顾问阿莫林
  • 时隔近4年再出征!长三丙成功发射通信技术试验卫星十九号
  • 铁路部门:确保沿线群众安全,焦柳铁路6个区段将陆续安装防护栅栏
  • 训练孩子的科学思维,上海虹口推出“六个一百”旗舰工程
  • 第12届警博会在即:一批便民利企装备亮相,规模创历史新高