Spring事务失效的原因及解决方案

 更新时间:2024年07月11日 09:17:59   作者:码农郭大大  
本文主要介绍了Spring事务失效的原因及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、spring方法调用导致事务失效原因

1、事务失效场景复现

1.1  背景原因

在循环中处理事务问题上,我们使用声明式事务有以下选择:

1.1.1 把@Transanal注解放在整个循环的方法上,这样整个循环都会被spring事务管理到,缺点是使用了长事务,会导致锁表问题,影响效率。

1.1.2 将每一次循环抽出一个方法,把@Transanal注解加在这个方法上。这样spring只管理了本次循环的事务,解决了长事务问题,但是有事务失效的风险。

1.2 场景模拟

@Repository
public class BookDao {
    @Transactional(propagation = Propagation.REQUIRED)
    public void updateStock(int id){
        String sql = "update book_stock set stock=stock-1 where id=?";
        jdbcTemplate.update(sql,id);
        for (int i = 1 ;i>=0 ;i--)
            System.out.println(10/i);
    }

    public void test(){
        this.updateStock(1);
    }
}

updateStock方法上@Transanal,会将updateStock方法交给spring事务管理;

test方法上无@Transanal,test方法不会交给spring事务管理。

测试的时候调用test方法的时候,发现test内部调用的updateStock时,updateStock的事务失效了;因为test内部调用的updateStock方法只是BookDao原对象的的原方法,而不是BookDao被代理对象的方法,所以事务失效

2、解决方案

通过事务失效的原因分析可知,我们只有调用代理对象的方法才会走事务

2.1 方法一

从容器中取出代理类,调用它的代理方法。可以通过实现ApplicationContextAware接口,获取IOC容器applicationContext对象,从容器中获取BookDao代理对象

@Repository
public class BookDao implements ApplicationContextAware {

    private  ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        applicationContext = applicationContext;
    }


    public void test(){
        BookDao bookDao = applicationContext.getBean(BookDao.class);
        bookDao.updateStock(1);
    }
    @Transactional(propagation = Propagation.REQUIRED)
    public void updateStock(int id){
        String sql = "update book_stock set stock=stock-1 where id=?";
        jdbcTemplate.update(sql,id);
        for (int i = 1 ;i>=0 ;i--)
            System.out.println(10/i);
    }
}

2.1 方法二

使用AOP暴露出来的代理对象,其本质也跟上面的一样,在启动类上加@EnableAspectJAutoProxy(exposeProxy = true),方法调用通过AopContext.currentProxy()获取代理对象

    public void test(){
        BookDao bookDao = (  BookDao)AopContext.currentProxy();
//        BookDao bookDao = applicationContext.getBean(BookDao.class);
        bookDao.updateStock(1);
    }

到此这篇关于Spring事务失效的原因及解决方案的文章就介绍到这了,更多相关Spring事务失效内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • SpringBoot响应出现中文乱码的解决方法

    SpringBoot响应出现中文乱码的解决方法

    这篇文章主要介绍了SpringBoot响应出现中文乱码的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作有一定的参考价值,需要的朋友们下面随着小编来一起来学习吧
    2024-02-02
  • IDEA SSM整合Redis项目实例 附源码

    IDEA SSM整合Redis项目实例 附源码

    今天给大家普及IDEA SSM整合Redis项目实例,包括pom.xml 配置和spring-redis.xml 配置代码,代码也很简单,通过项目实际案例能更好的帮助大家理解,需要的朋友可以参考下
    2021-06-06
  • 基于JavaSwing设计和实现的酒店管理系统

    基于JavaSwing设计和实现的酒店管理系统

    这篇文章主要介绍了基于JavaSwing+mysql的酒店管理系统设计和实现,它可以实现酒店日常的管理功能包括开房、退房、房间信息、顾客信息管理等
    2021-08-08
  • 浅谈Java中hashCode的正确求值方法

    浅谈Java中hashCode的正确求值方法

    这篇文章主要介绍了浅谈Java中hashCode的正确求值方法,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • SpringBoot集成JWT令牌详细说明

    SpringBoot集成JWT令牌详细说明

    这篇文章主要介绍了SpringBoot集成JWT令牌详细说明,JWT方式校验方式更加简单便捷化,无需通过redis缓存,而是直接根据token取出保存的用户信息,以及对token可用性校验,单点登录,验证token更为简单,需要的朋友可以参考下
    2023-10-10
  • Spring 4.0新功能:@Conditional注解详细介绍

    Spring 4.0新功能:@Conditional注解详细介绍

    Spring Boot的强大之处在于使用了Spring 4框架的新特性:@Conditional注释,此注释使得只有在特定条件满足时才启用一些配置。下面这篇文章主要给大家介绍了关于Spring4.0中新功能:@Conditional注解的相关资料,需要的朋友可以参考下。
    2017-09-09
  • MyBatis全局配置文件详解

    MyBatis全局配置文件详解

    这篇文章主要介绍了mybatis 加载配置文件的方法,通过实例代码给大家介绍了mybatis 加载配置文件的两种方式,需要的朋友可以参考下
    2021-07-07
  • IDEA的崛起自己定义快捷生成代码块的详细步骤

    IDEA的崛起自己定义快捷生成代码块的详细步骤

    这篇文章主要介绍了IDEA的崛起自己定义快捷生成代码块的详细步骤,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • Java反射机制的实现详解

    Java反射机制的实现详解

    反射主要解决动态编程,即使用反射时,所有的对象生成是动态的,因此调用的方法也是动态的.反射可以简化开发,但是代码的可读性很低
    2013-05-05
  • Java利用递归实现树形结构的工具类

    Java利用递归实现树形结构的工具类

    有时候,我们的数据是带有层级的,比如常见的省市区三级联动,就是一层套着一层。而我们在数据库存放数据的时候,往往是列表形式的,这个时候可能就需要递归处理为树形结构了。本文就为大家介绍了Java利用递归实现树形结构的工具类,希望对大家有所帮助
    2023-03-03

最新评论