暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

[Spring/JAVA]事务传播机制

西瓜爸爸 2022-07-17
288

总结

  • Spring 事务的传播机制,支持继续使用当前事务的主要有Propagation.REQUIRED,Propagation.SUPPORTS,Propagation.MANDATORY,不支持继续使用当前事务的包括Propagation.REQUIRES_NEW,Propagation.NOT_SUPPORTED,Propagation.NEVER。还有一个与 REQUIRED 行为类似的 NESTED 嵌套传播。

  • Spring 事务传播时,判断两个方法是否属于同一个事务,关键还得看他们是否使用相同的数据库连接。

  • Spring 事务是基于 AOP 的,所以直接使用 this 方法会导致“事务失效”。

Spring事务类型

事务例子

外层异常

代码段

     @Transactional(propagation = Propagation.XXX)
    public void createUser(String name) {
    // 新增用户基本信息
    jdbcTemplate.update("INSERT INTO `user` (name) VALUES(?)", name);
    //调用accountService添加帐户
    accountService.addAccount(name, 10000);
    // 出现分母为零的异常
    int i = 1 0;
    }

    测试结果

    内层异常

    代码段

      public class UserService {
      // ...
      @Transactional(propagation = Propagation.REQUIRED)
      public void createUser(String name) {
      jdbcTemplate.update("INSERT INTO `user` (name) VALUES(?)", name);
      accountService.addAccount(name, 10000);
      }
      }


      @Service
      public class AccountService {
      // ...
      @Transactional(propagation = Propagation.XXX)
      public void addAccount(String name, int initMoney) {
      String accountid = new SimpleDateFormat("yyyyMMddhhmmss").format(new Date());
      jdbcTemplate.update("insert INTO account (account_name,user,money) VALUES (?,?,?)", accountid, name, initMoney);
      // 出现分母为零的异常
      int i = 1 0;
      }
      }

      测试结果

      问题

      非事务方法与事务方法执行相互调用不生效

      问题描述: 

      同一个service内互相调用,事务情况仅为第一个public方法的事务,不会更变。

      原因: 

      在一个Service内部,事务方法之间的嵌套调用,普通方法和事务方法之间的嵌套调用,都不会开启新的事务。是因为spring采用动态代理机制来实现事务控制,而动态代理最终都是要调用原始对象的,而原始对象在去调用方法时,是不会再触发代理了!

      解决方法: 

      • springboot启动类加上注解: @EnableAspectJAutoProxy(exposeProxy = true)
         

      • Service实现类 变量名= (Service实现类) AopContext.currentProxy();



      文章转载自西瓜爸爸,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

      评论