Spring声明式事务及其原理

本文涉及的产品
RDS Agent(兼容OpenClaw),2核4GB
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
简介: Spring声明式事务及其原理

声明式事务及其原理

1.环境搭建:

1、导入相关依赖:数据源、数据库驱动、Spring-jdbc模块

  <dependency>
      <groupId>c3p0</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.1.2</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.44</version>
    </dependency>
    <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-jdbc</artifactId>
          <version>5.0.2.RELEASE</version>
      </dependency>

2.建立数据表:

dc64dd5224eb413d98156a1538f931b7.png

3.编写测试类:

#############################################TxConfig配置类##############################
/**
* 1、导入相关依赖
*     数据源、数据库驱动、Spring-jdbc模块
* 2、配置数据源、JdbcTemplate(Spring提供的简化数据库操作的工具)操作数据
*/
@ComponentScan("com.rg.tx")
@Configuration
public class TxConfig {
    //数据源
    @Bean
    public DataSource dataSource() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser("root");
        dataSource.setPassword("186259");
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql:///test");
        return dataSource;
    }
    @Bean
    public JdbcTemplate jdbcTemplete() throws Exception {
        //Spring对@Configuration类会特殊处理; 对于给容器中加组件的方法,多次调用只是从容器中找组件然后使用.
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
        return jdbcTemplate;
    }
}
###################################################UserDao##############################
@Repository
public class UserDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    public void insert(){
        String sql = "INSERT INTO USER(username,PASSWORD) VALUES(?,?)";
        String username = UUID.randomUUID().toString().substring(0, 5);
        jdbcTemplate.update(sql,username,21);
    }
}
############################################UserService##################################
 @Service
public class UserService {
    @Autowired
    private UserDao userDao;
    public void insertUser(){
        userDao.insert();
        System.out.println("插入完成...");
    }
}

2.添加事务机制

  1. 给方法上标注 @Transactional 表示当前方法是一个事务方法;
  2. **@EnableTransactionManagement **开启基于注解的事务管理功能;
  3. 配置事务管理器来控制事务;
@Bean
public PlatformTransactionManager transactionManager(){
    ...
}

实现代码:

######################################TxConfig########################################
@EnableTransactionManagement
@ComponentScan("com.rg.tx")
@Configuration
public class TxConfig {
    ...
         //注册事务管理器到容器中
    @Bean
    public PlatformTransactionManager transactionManager() throws Exception {
        return new DataSourceTransactionManager(dataSource());
    }
}
###################################UserService########################################
@Service
public class UserService {
    @Autowired
    private UserDao userDao;
    @Transactional
    public void insertUser(){
        userDao.insert();
        //otherDao.other();
        System.out.println("插入完成...");
        int i = 10 / 0;
    }
}

3. @EnableTransactionManagement原理

 * 原理:
 * 1)、@EnableTransactionManagement
 *      利用TransactionManagementConfigurationSelector给容器中会导入两个组件
 *      AutoProxyRegistrar
 *      ProxyTransactionManagementConfiguration
 * 2)、AutoProxyRegistrar:
 *      给容器中注册一个 InfrastructureAdvisorAutoProxyCreator 组件(原理和                           AnnotationAwareAspectJAutoProxyCreator类似)
 *      
      利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行调用;
 *
 * 3)、ProxyTransactionManagementConfiguration 做了什么?
 *      1、给容器中注册事务增强器;
 *        1)、事务增强器要用事务注解的信息,AnnotationTransactionAttributeSource解析事务注解
 *        2)、事务拦截器:
 *          TransactionInterceptor;保存了事务属性信息,事务管理器;
 *          他是一个 MethodInterceptor;
 *          在目标方法执行的时候;
 *            执行拦截器链;
 *            事务拦截器:
 *              1)、先获取事务相关的属性
 *              2)、再获取PlatformTransactionManager,如果事先没有添加指定任何transactionmanger
 *                最终会从容器中按照类型获取一个PlatformTransactionManager;
 *              3)、执行目标方法
 *                如果异常,获取到事务管理器,利用事务管理回滚操作;
 *                如果正常,利用事务管理器,提交事务
 *
 */
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
9月前
|
缓存 Java 开发者
【Spring】原理:Bean的作用域与生命周期
本文将围绕 Spring Bean 的作用域与生命周期展开深度剖析,系统梳理作用域的类型与应用场景、生命周期的关键阶段与扩展点,并结合实际案例揭示其底层实现原理,为开发者提供从理论到实践的完整指导。
1022 22
|
9月前
|
SQL Java 关系型数据库
Spring事务传播机制:7种姿势教你玩转"事务接力赛"
事务传播机制是Spring框架中用于管理事务行为的重要概念,它决定了在方法调用时事务如何传递与执行。通过7种传播行为,开发者可以灵活控制事务边界,适应不同业务场景。例如:REQUIRED默认加入或新建事务,REQUIRES_NEW独立开启新事务,NESTED支持嵌套回滚等。合理使用传播机制不仅能保障数据一致性,还能提升系统性能与健壮性。掌握这“七种人格”,才能在复杂业务中游刃有余。
|
9月前
|
人工智能 Java 开发者
【Spring】原理解析:Spring Boot 自动配置
Spring Boot通过“约定优于配置”的设计理念,自动检测项目依赖并根据这些依赖自动装配相应的Bean,从而解放开发者从繁琐的配置工作中解脱出来,专注于业务逻辑实现。
2872 0
|
8月前
|
XML Java 测试技术
《深入理解Spring》:IoC容器核心原理与实战
Spring IoC通过控制反转与依赖注入实现对象间的解耦,由容器统一管理Bean的生命周期与依赖关系。支持XML、注解和Java配置三种方式,结合作用域、条件化配置与循环依赖处理等机制,提升应用的可维护性与可测试性,是现代Java开发的核心基石。
|
8月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
738 2
|
10月前
|
Java 关系型数据库 数据库
深度剖析【Spring】事务:万字详解,彻底掌握传播机制与事务原理
在Java开发中,Spring框架通过事务管理机制,帮我们轻松实现了这种“承诺”。它不仅封装了底层复杂的事务控制逻辑(比如手动开启、提交、回滚事务),还提供了灵活的配置方式,让开发者能专注于业务逻辑,而不用纠结于事务细节。
1182 1
|
前端开发 Java 数据库连接
Spring核心原理剖析与解说
每个部分都是将一种巨大并且复杂的技术理念传达为更易于使用的接口,而这就是Spring的价值所在,它能让你专注于开发你的应用,而不必从头开始设计每一部分。
331 32
|
人工智能 Java 数据库连接
Spring事务失效场景
本文深入探讨了Spring框架中事务管理可能失效的几种常见场景及解决方案,包括事务方法访问级别不当、方法内部自调用、错误的异常处理、事务管理器或数据源配置错误、数据库不支持事务以及不合理的事务传播行为或隔离级别。通过合理配置和正确使用`@Transactional`注解,开发者可以有效避免这些问题,确保应用的数据一致性和完整性。
1092 10
|
11月前
|
缓存 安全 Java
Spring 框架核心原理与实践解析
本文详解 Spring 框架核心知识,包括 IOC(容器管理对象)与 DI(容器注入依赖),以及通过注解(如 @Service、@Autowired)声明 Bean 和注入依赖的方式。阐述了 Bean 的线程安全(默认单例可能有安全问题,需业务避免共享状态或设为 prototype)、作用域(@Scope 注解,常用 singleton、prototype 等)及完整生命周期(实例化、依赖注入、初始化、销毁等步骤)。 解析了循环依赖的解决机制(三级缓存)、AOP 的概念(公共逻辑抽为切面)、底层动态代理(JDK 与 Cglib 的区别)及项目应用(如日志记录)。介绍了事务的实现(基于 AOP
410 0
|
11月前
|
监控 架构师 NoSQL
spring 状态机 的使用 + 原理 + 源码学习 (图解+秒懂+史上最全)
spring 状态机 的使用 + 原理 + 源码学习 (图解+秒懂+史上最全)