同一个类中方法调用事务生效问题测试

tips:

  • Transactional注解必须用在public方法上
  • spring aop依赖于aspectjweaver
  • 使用AopContext.currentProxy必须在启动类上加@EnableAspectJAutoProxy(exposeProxy = true)

同一个类调用不生效的情况如下

@Component
public class TestService {

  @Autowired
  JdbcTemplate jdbcTemplate;

//  @Transactional(rollbackFor = Exception.class) 这里没加事务
  public void contextLoads() {
    jdbcTemplate.update("update localtest set attr1=? where id=?", new Object[]{"aaaa", 1});
//    ((TestService)AopContext.currentProxy()).test();
    this.test(); // 这里直接调用,此时test异常了也不会回滚
  }

  @Transactional(rollbackFor = Exception.class)
  public void test() {
    jdbcTemplate.update("update localtest set attr1=? where id=?", new Object[]{"aaaa", 2});
    int a = 1/0;
  }
}

  1. 使用TransactionAspectSupport
 @Transactional(rollbackFor = Exception.class)
  public void contextLoads() {
    jdbcTemplate.update("update localtest set attr1=? where id=?", new Object[]{"aaaa", 1});
    try {
//      ((TestService)AopContext.currentProxy()).test();
      this.test();
    } catch (Exception e) {
      TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    }
  }

  @Transactional(rollbackFor = Exception.class)
  public void test() {
    jdbcTemplate.update("update localtest set attr1=? where id=?", new Object[]{"aaaa", 2});
    int a = 1/0;
  }
  1. 自己抛出RuntimeException
  @Transactional(rollbackFor = Exception.class)
  public void contextLoads() {
    jdbcTemplate.update("update localtest set attr1=? where id=?", new Object[]{"aaaa", 1});
    try {
//      ((TestService)AopContext.currentProxy()).test();
      this.test();
    } catch (Exception e) {
//      TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
      throw new RuntimeException();
    }
  }

  @Transactional(rollbackFor = Exception.class)
  public void test() {
    jdbcTemplate.update("update localtest set attr1=? where id=?", new Object[]{"aaaa", 2});
    int a = 1/0;
  }
  1. 使用AopContext.currentProxy
  @Transactional(rollbackFor = Exception.class)
  public void contextLoads() {
    jdbcTemplate.update("update localtest set attr1=? where id=?", new Object[]{"aaaa", 1});
    ((TestService)AopContext.currentProxy()).test();
  }

  @Transactional(rollbackFor = Exception.class)
  public void test() {
    jdbcTemplate.update("update localtest set attr1=? where id=?", new Object[]{"aaaa", 2});
    int a = 1/0;
  }
  1. 不用声明式事务,手动提交和回滚
public class TestService {

  @Autowired
  JdbcTemplate jdbcTemplate;
  @Autowired
  ObjectMapper objectMapper;
  @Autowired
  DataSourceTransactionManager dataSourceTransactionManager;
  @Autowired
  TransactionDefinition transactionDefinition;

//  @Transactional(rollbackFor = Exception.class) // 这里没加事务
  public void contextLoads() {
    TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);

    try {
      jdbcTemplate.update("update localtest set attr1=? where id=?", new Object[]{"aaaa", 1});
      this.test();
      int a = 1/0;
      dataSourceTransactionManager.commit(transactionStatus);
    } catch (Exception e) {
      System.out.println(e);
//      TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
      dataSourceTransactionManager.rollback(transactionStatus);
      String a = null;
      try {
        a = objectMapper.writeValueAsString(e);
      } catch (JsonProcessingException ex) {
        ex.printStackTrace();
      }
      jdbcTemplate.update("update localtest set attr3=? where id=?", new Object[]{a, 1});
    }
  }


  @Transactional(rollbackFor = Exception.class)
  public void test() {
    jdbcTemplate.update("update localtest set attr1=? where id=?", new Object[]{"aaaa", 2});
  }
}

你可能感兴趣的:(同一个类中方法调用事务生效问题测试)