美文网首页
spring|事务底层原理分析

spring|事务底层原理分析

作者: ajajaj | 来源:发表于2020-08-08 16:46 被阅读0次

    spring本身没有事务,spring事务是在数据库事务的基础上进行封装拓展,spring支持声明式事务、编程式事务两种,本文主要针对声明式事务进行讲解,本篇文章为《图灵学院》课程笔记

    我们在使用事务的时候无非是以下几步

    • 获取数据库连接 Connection con = DriverManager.getConnection()
    • 开启事务con.setAutoCommit(true/false);
    • 执行数据操作(crud)
    • 提交事务/回滚事务 con.commit() / con.rollback()
    • 关闭连接 conn.close()

    其实spring是在框架中给我我们做了开启、提交/回滚的操作,使得业务代码和事务操作解耦。那么spring是如何实现在指定方法前后自动加上事务操作的呢;这就要扯到动态代理了

    代理模式

    • 解决的问题:将次要业务、主要业务解耦。,次要业务:起到辅助作用,辅助主要业务顺利实现,在项目中往往大量存在

    具体例子如下:

    接口

    public interface UserDao {
         void save();
    }
    

    接口实现、目标对象

    public class UserDaoImpl implements UserDao {
        @Override
        public void save() {
            System.out.println("数据已经保存");
        }
    }
    

    代理对象

    public class ProxyFactory {
    
        private  Object target;
    
        public ProxyFactory(Object object) {
            this.target = object;
        }
    
        public Object getProxyObject(){
           return  Proxy.newProxyInstance(target.getClass().getClassLoader(),
                     target.getClass().getInterfaces(),new InvocationHandler(){
                       /**
                        * @param proxy 负责监听的对象
                        * @param method 被拦截的业务方法
                        * @param args 被拦截业务方法的实参
                        * @return
                        * @throws Throwable
                        */
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            System.out.println("before do something...");
                             Object returnValue= method.invoke(target,args);
                            System.out.println("after do something...");
                            return returnValue;
                        }
                    });
        }
    }
    

    测试方法

       public static void main(String[] args) {
            //目标对象
            UserDao target = new UserDaoImpl();
            //目标对象创建代理对像
            UserDao proxy = (UserDao) new ProxyFactory(target).getProxyObject();
            proxy.save();
        }
    

    输出结果

    image

    结合着代理模式,spring事务的实现原理就容易理解了,业务逻辑就是主要业务,需要重复使用的事务就是次要业务,spring的事务就是通过动态代理在业务代码的前后增加开启、提交/回滚的操作,实现事务操作

    spring事务特性如下

    • 支持原有数据事务的隔离级别
    • 加入事务传播特性概念,提供多个事务的合并或隔离的功能
    • 提供声明式事务,让业务代码和事务分离,事务简单易用

    spring事务的传播特性

    image

    spring事务隔离级别

    隔离级别 脏读(Dirty Read) 不可重复读(NonRepeatable Read) 幻读(Phantom Read)
    未提交读(Read uncommitted) 可能 可能 可能
    已提交读(Read committed) 不可能 可能 可能
    可重复读(Repeatable read) 不可能 不可能 可能
    可串行化(SERIALIZABLE) 不可能 不可能 不可能

    脏读 :

    一个事物读取到另一事物未提交的更新数据

    不可重复读 :

    在同一事物中,多次读取同一数据返回的结果有所不同, 换句话说, 后续读取可以读到另一事物已提交的更新数据. 相反, “可重复读”在同一事物中多次读取数据时, 能够保证所读数据一样, 也就是后续读取不能读到另一事物已提交的更新数据。

    幻读 :

    查询表中一条数据如果不存在就插入一条,并发的时候却发现,里面居然有两条相同的数据。这就幻读的问题。

    spring提供三个接口提供使用事务:

    • TransactionDefinition 事务定义

      image
    • PlatformTransactionManager 事务管理

      image
    • TransactionStatus 事务运行时状态

      image

    原文地址

    http://cbaj.gitee.io/blog/2020/08/08/spring%7C%E4%BA%8B%E5%8A%A1%E5%BA%95%E5%B1%82%E5%8E%9F%E7%90%86%E5%88%86%E6%9E%90/#more

    相关文章

      网友评论

          本文标题:spring|事务底层原理分析

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