美文网首页
spring的事务管理器

spring的事务管理器

作者: 念䋛 | 来源:发表于2022-09-23 15:51 被阅读0次

事务管理器在实际的开发过程中主要是配合注解的使用,也可以在代码中手动的创建事务管理器,
注解是结合@Transaction注解,手动的可以在网上找一些资料,创建TransactionTemplate手动的调用execute方法.
事务管理器的作用是什么呢,其实就是connection的自动提交设置成false,方法执行结束后统一的commit或者rollback,道理是很简单的.


image.png

如果没有事务管理器,那两条sql语句,就得手动的获取connection,并讲自动提交设置为false,再统一提交或者回滚

 public static void main(String[] args) throws IOException, SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException{
        // 1 提供Properties实例对象
        Properties pros = new Properties();
        FileInputStream fs = new FileInputStream("C:\\Users\\DuoDuo\\Desktop\\codeTest\\springboottest\\src\\main\\resources\\jdbc.properties");
        pros.load(fs);
        // 2 读取配置信息
        String url = pros.getProperty("url");
        String user = pros.getProperty("username");
        String password = pros.getProperty("password");
        String driverClass = pros.getProperty("driver-class-name");
        // 4 加载驱动
        Class<Driver> clazz = (Class<Driver>) Class.forName(driverClass);
        Driver driver = clazz.newInstance();
        // 5 注册驱动
        DriverManager.registerDriver(driver);
        // 6 获取对象
        Connection conn = DriverManager.getConnection(url, user, password);
        // 7 取消自动提交
        conn.setAutoCommit(false);
        // 8 获取Statement
        PreparedStatement preparedStatement = conn.prepareStatement("select * from empage");
        // 9 执行sql  这里省略多条的update语句
        ResultSet resultSet = preparedStatement.executeQuery();
        // 10 打印
        while(resultSet.next()){
            int id = resultSet .getInt("id");
            String ename = resultSet .getString("ename");
            int age = resultSet .getInt("age");
            System.out.println(id+ename+age);
        }
        //11 自动提交 or rollback
        conn.commit();
    }

在spring项目中,可以从容器中获取datasource,再Connection connection = dataSource.getConnection();获取连接,一般都是从连接池中获取连接
从示例中也可以看到,java是如何与数据库交换数据的,PreparedStatement是驱动自己去实现的,本例使用的是mysql驱动

有了事务管理器之后,十分的方便,如果结合了spring只需要一个注解就可以实现,本文重点分析使用注解的方式,结合mybatis是如何工作的
1.数据源datasource
org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.Hikari#dataSource
spring默认使用的是HikariDataSource数据源


image.png

2.事务管理器
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration.JdbcTransactionManagerConfiguration#transactionManager
默认使用的是DataSourceTransactionManager


image.png
3.@Transaction如何包装当前类
通过springboot的自动配置特性引入TransactionAutoConfiguration
image.png
spring.factories文件引入TransactionAutoConfiguration配置类
自己通过debug的方式,查看调用链,执行registerAutoProxyCreatorIfNecessary方法

org.springframework.aop.config.AopConfigUtils#registerAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)


image.png
将InfrastructureAdvisorAutoProxyCreator注入近BeanDefinitionMap中
InfrastructureAdvisorAutoProxyCreator是AbstractAutoProxyCreator接口的子类,注意postProcessAfterInitialization这个方法,这是bean的后置处理器,上面提到InfrastructureAdvisorAutoProxyCreator类已经注入进容器里,当创建bean的时候就会调用postProcessAfterInitialization后置处理器
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization中wrapIfNecessary(bean, beanName, cacheKey)方法
当前的bean是否被aop切面命中,图中getAdvicesAndAdvisorsForBean方法判断当前类或者当前类的方法是否标注了@Transaction,如果标注创建代理类,getAdvicesAndAdvisorsForBean也判断了是否被AOP命中,@AspectJ 的几个注解
image.png
spring中默认添加的关于事务的Advisor,Advisor就是aop的切面,pointcut切点,可以去网上查一下资料
如果类中有一个方法标注了@Transaction,当前类就会被代理
image.png
4.sql的执行
cglib代理类的第一个callback是DynamicAdvisedInterceptor
执行标注了@Transaction注解的方法的时候,会被拦截,图中就是DynamicAdvisedInterceptor,chain就是拦截链路TransactionInterceptor
image.png
方法调用之前会被拦截,跳过一些方法,参考图中跳过的方法,调用到doBegin方法
org.springframework.jdbc.datasource.DataSourceTransactionManager#doBegin
image.png
image.png

bindResource方法将连接放到threadlocal中,后续会被获取,因为这里只是创建了一个connection,并没有执行sql,后续再mybatis中从线程中获取连接执行sql
TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());


image.png
mybatis的执行
org.apache.ibatis.executor.SimpleExecutor#prepareStatement
image.png
image.png
从threadloacl中获取连接,这就保证了spring事务开启的时候创建的connection和mybatis执行sql使用的connection是同一个,因为spring开启事务的时候的连接取消了自动提交,保证了事务
当方法执行结束后事务的提交
org.springframework.transaction.interceptor.TransactionAspectSupport#commitTransactionAfterReturning
image.png
事务结束,整体的事务大概的流程就这式样,保证spring开始事务的时候连接和实际执行sql的连接是同一个,并且开启事务的时候取消自动提交,在事务结束的时候提交事务或者回滚.

相关文章

  • spring事务

    1、spring事务管理器PlatformTransactionManager 1.1、没有spring事务管理器...

  • 关于事务的思考

    Spring对于事务的支持 Spring事务接口 Spring事务管理器 Spring并不直接管理事务,而是提供多...

  • Spring事务管理

    一、事务管理器事务管理器.png 二、事务的传播规则 Spring 在 TransactionDefinition...

  • Spring事务

    容器事务 Spring事务核心接口 JDBC事务管理器(DataSourceTransactionManager)...

  • spring 事务管理

    1、PlatformTransactionManager 事务管理器spring要管理事务必须使用事务管理器。进行...

  • Spring的事务管理

    一.Spring事务管理API介绍 1.事务管理器事务管理器是PlatformTransactionManager...

  • 引入spring事务管理

    1.1 为什么用spring事务管理? 在没有spring事务管理器之前,java开发者通常有两种事务管理器可供选...

  • Spring 事务

    Spring可以支持编程式事务和声明式事务。 编程式事务 实现 Spring使用事务管理器,每个不同平台的事务管理...

  • 第五章 Spring的事务管理

    事务的核心接口 PlatformTransactionManager接口(spring提供的平台事务管理器) 主要...

  • Spring事务管理详解

    Spring事务介绍 Spring并不直接管理事务,而是提供了多种事务管理器,他们将事务管理的职责委托给Hiber...

网友评论

      本文标题:spring的事务管理器

      本文链接:https://www.haomeiwen.com/subject/iefnortx.html