【Spring事务底层实现原理】

简介: 【Spring事务底层实现原理】

@Transactional注解

Spring使用了TransactionInterceptor拦截器,该拦截器主要负责事务的管理,包括开启、提交、回滚等操作。当在方法上添加@Transactional注解时,Spring会在AOP框架中对该方法进行拦截,TransactionInterceptor会在该方法执行前后,对事务进行切面处理,Spring会基于该类生成一个代理对象,把这个代理对象作为bean。当调用这个代理对象的方法时,如果有事务处理,则会先关闭事务的自动功能,然后执行方法的具体业务逻辑,如果业务逻辑没有异常,那么代理逻辑就会直接提交,如果出现任何异常,那么直接进行回滚操作。

事务管理器

Spring还提供了多种事务管理器,包括JDBC事务管理器、Hibernate事务管理器、JTA事务管理器等等,可以满足不同数据访问层的需求。事务通知是Spring事务机制中的一个重要组成部分,主要用于判断哪些方法需要被事务管理,以及如何管理事务。

Spring事务底层实现原理

应用启动时会创建一个代理类,把事务逻辑织入到代理类中,然后用代理类替代目标类,并放入上下文容器中。当实际调用目标类的事务方法时,被代理类拦截,先执行拦截器中的事务逻辑,再执行目标类的业务逻辑,最后处理异常回滚和提交。这样就能实现简单、方便、可控的事务管理。

示例代码

这里给出一个简单的示例代码:

定义一个接口,包含需要进行事务管理的方法:

public interface UserService {
    void addUser(User user);
    void deleteUser(String id);
    void updateUser(User user);
    User getUser(String id);
}

实现这个接口的目标类:

public class UserServiceImpl implements UserService {
    @Override
    public void addUser(User user) {
        //添加用户的业务逻辑
    }
    @Override
    public void deleteUser(String id) {
        //删除用户的业务逻辑
    }
    @Override
    public void updateUser(User user) {
        //更新用户的业务逻辑
    }
    @Override
    public User getUser(String id) {
        //查询用户的业务逻辑
        return null;
    }
}

定义一个事务拦截器类:

/**
 * TransactionInterceptor 是一个实现了 MethodInterceptor 接口的拦截器类
 */
public class TransactionInterceptor implements MethodInterceptor {
    /**
     * TransactionManager 对象,用于管理事务
     */
    private TransactionManager txManager;
    /**
     * 用于注入 TransactionManager 对象
     * @param txManager TransactionManager 对象
     */
    public void setTxManager(TransactionManager txManager) {
        this.txManager = txManager;
    }
    /**
     * 实现 MethodInterceptor 接口的 invoke 方法,用于拦截指定方法
     * @param invocation MethodInvocation 对象,用于获取被拦截的方法及其参数
     * @return 执行方法的返回结果
     * @throws Throwable 抛出异常
     */
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Object result;
        try {
            // 开启事务
            txManager.start();
            // 执行被拦截的方法,并获取方法执行的返回结果
            result = invocation.proceed();  
            // 提交事务
            txManager.commit();
        } catch (Exception e) {
            // 回滚事务
            txManager.rollback();
            throw e;
        }
        return result;
    }
}

定义一个上下文容器类:

public class ApplicationContext {
    private Map<String, Object> beanMap = new HashMap<>(); // 用于存放bean的map
    // 注册bean
    public void registerBean(String name, Object bean) {
        beanMap.put(name, bean); // 将bean存放到map中
    }
    // 获取bean
    public Object getBean(String name) {
        Object bean = beanMap.get(name); // 从map中获取bean
        if (bean instanceof Advised) { // 如果bean是Advised类型,说明使用了AOP
            return ((Advised)bean).getTargetSource().getTarget(); // 返回目标对象
        }
        return bean; // 返回原始对象
    }
}

在应用启动时,创建一个代理工厂类,使用上述事务拦截器对目标类进行代理:

/**
 * 代理工厂类,用于创建代理对象
 */
public class ProxyFactory {
    /**
     * 创建代理对象
     * @param target 目标对象,需要被代理的对象
     * @param interceptor 事务拦截器,代理对象需要加入该拦截器
     * @return 返回代理对象
     */
    public static Object createProxy(Object target, TransactionInterceptor interceptor) {
        DefaultAopProxyFactory proxyFactory = new DefaultAopProxyFactory();
        AdvisedSupport advisedSupport = new AdvisedSupport();
        advisedSupport.setTarget(target); // 设置目标对象
        advisedSupport.addAdvice(interceptor); // 添加事务拦截器
        return proxyFactory.createAopProxy(advisedSupport).getProxy(); // 创建代理对象并返回
    }
}

然后在应用启动时,创建容器并注册代理类:

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ApplicationContext();
        UserService target = new UserServiceImpl(); //创建目标类
        TransactionInterceptor interceptor = new TransactionInterceptor();
        interceptor.setTxManager(new TransactionManager()); //设置事务管理器
        UserService proxy = (UserService) ProxyFactory.createProxy(target, interceptor); //创建代理类
        context.registerBean("userService", proxy); //注册代理类到上下文容器中
        //使用代理类进行业务操作
        User user = new User();
        context.getBean("userService").addUser(user);
    }
}

这样,当执行代理类的方法时,就会先执行事务拦截器中的事务逻辑,再执行目标类的业务逻辑。如果出现异常,会进行回滚。这样就实现了简单、方便、可控的事务管理。


相关文章
|
2月前
|
XML Java 开发者
Spring Boot开箱即用可插拔实现过程演练与原理剖析
【11月更文挑战第20天】Spring Boot是一个基于Spring框架的项目,其设计目的是简化Spring应用的初始搭建以及开发过程。Spring Boot通过提供约定优于配置的理念,减少了大量的XML配置和手动设置,使得开发者能够更专注于业务逻辑的实现。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,为开发者提供一个全面的理解。
37 0
|
5天前
|
Java 开发者 Spring
理解和解决Spring框架中的事务自调用问题
事务自调用问题是由于 Spring AOP 代理机制引起的,当方法在同一个类内部自调用时,事务注解将失效。通过使用代理对象调用、将事务逻辑分离到不同类中或使用 AspectJ 模式,可以有效解决这一问题。理解和解决这一问题,对于保证 Spring 应用中的事务管理正确性至关重要。掌握这些技巧,可以提高开发效率和代码的健壮性。
31 13
|
17天前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
67 14
|
1月前
|
缓存 安全 Java
Spring高手之路26——全方位掌握事务监听器
本文深入探讨了Spring事务监听器的设计与实现,包括通过TransactionSynchronization接口和@TransactionalEventListener注解实现事务监听器的方法,并通过实例详细展示了如何在事务生命周期的不同阶段执行自定义逻辑,提供了实际应用场景中的最佳实践。
45 2
Spring高手之路26——全方位掌握事务监听器
|
1月前
|
Java 关系型数据库 数据库
京东面试:聊聊Spring事务?Spring事务的10种失效场景?加入型传播和嵌套型传播有什么区别?
45岁老架构师尼恩分享了Spring事务的核心知识点,包括事务的两种管理方式(编程式和声明式)、@Transactional注解的五大属性(transactionManager、propagation、isolation、timeout、readOnly、rollbackFor)、事务的七种传播行为、事务隔离级别及其与数据库隔离级别的关系,以及Spring事务的10种失效场景。尼恩还强调了面试中如何给出高质量答案,推荐阅读《尼恩Java面试宝典PDF》以提升面试表现。更多技术资料可在公众号【技术自由圈】获取。
|
2月前
|
Java 开发者 Spring
Spring高手之路24——事务类型及传播行为实战指南
本篇文章深入探讨了Spring中的事务管理,特别是事务传播行为(如REQUIRES_NEW和NESTED)的应用与区别。通过详实的示例和优化的时序图,全面解析如何在实际项目中使用这些高级事务控制技巧,以提升开发者的Spring事务管理能力。
61 1
Spring高手之路24——事务类型及传播行为实战指南
|
2月前
|
Java 开发者 Spring
Spring AOP 底层原理技术分享
Spring AOP(面向切面编程)是Spring框架中一个强大的功能,它允许开发者在不修改业务逻辑代码的情况下,增加额外的功能,如日志记录、事务管理等。本文将深入探讨Spring AOP的底层原理,包括其核心概念、实现方式以及如何与Spring框架协同工作。
|
2月前
|
JavaScript Java 关系型数据库
Spring事务失效的8种场景
本文总结了使用 @Transactional 注解时事务可能失效的几种情况,包括数据库引擎不支持事务、类未被 Spring 管理、方法非 public、自身调用、未配置事务管理器、设置为不支持事务、异常未抛出及异常类型不匹配等。针对这些情况,文章提供了相应的解决建议,帮助开发者排查和解决事务不生效的问题。
|
2月前
|
XML Java 数据库连接
Spring中的事务是如何实现的
Spring中的事务管理机制通过一系列强大的功能和灵活的配置选项,为开发者提供了高效且可靠的事务处理手段。无论是通过注解还是AOP配置,Spring都能轻松实现复杂的事务管理需求。掌握这些工具和最佳实践,能
70 3
|
3月前
|
Java Spring 容器
Spring底层原理大致脉络
Spring底层原理大致脉络