回滚 Spring 中嵌套事务中的所有数据库提交

Rollback All DB Commits in Nested Transactions in Spring

我有以下嵌套事务的服务布局:

@Component
public class Main implements RPCInterface {

  @Autowired
  private ServiceA serviceA;

  @Autowired
  private ServiceB serviceB;

  @Autowired
  private ServiceC serviceC;

  @Override
  @Transactional (value="txManager", propagation=Propagation.REQUIRED, rollbackFor={ExceptionOne.class, ExceptionTwo.class, ExceptionThree.class})
  public void outerMethod() throws ExceptionO {

    try {
      serviceA.methodA();
      serviceB.methodB();
      serviceC.methodC();

    } catch (ExceptionOne e) {
      throw new ExceptionO(e.getMessage, e);
    } catch (ExceptionTwo e) {
      throw new ExceptionO(e.getMessage, e);
    } catch (ExceptionThree e) {
      throw new ExceptionO(e.getMessage, e);
    }
  }
}

@Service
public class ServiceA implements SA {

  @Autowired
  private ServiceA1 serviceA1;

  @Override
  public void methodA() {
    serviceA1.methodA1();
  }
}

@Service
public class ServiceA1 implements SA1 {
  @Autowired
  private ServiceDBTable1 serviceDBTable1;

  @Autowired
  private ServiceA1A serviceA1A;

  @Transactional
  @Override
  public void methodA1() {
    serviceDBTable4.callToMapper4();
    serviceA1A.methodA1A();
  }
}

@Service
@Transactional (value="txManager", propagation=Propagation.REQUIRED)
public class ServiceA1A implements SA1A {

  @Autowired
  private ServiceDBTable2 serviceDBTable2;

  @Override
  public void methodA1A() {
    serviceDBTable1.callToMapper1();
  }
}

@Service
public class ServiceB implements SB {

  @Autowired
  private ServiceDBTable3 serviceDBTable3;

  @Override
  @Transactional (value="txManager", propagation=Propagation.REQUIRED)
  public void methodB() {
    serviceDBTable3.callToMapper3();
  }
}

@Service
public class ServiceC implements SC {

  @Override
  public void methodC() throws ExceptionThree {
    // code that throws ExceptionThree
  }
}

我需要在 ServiceAServiceB 嵌套调用中进行所有 DB 调用,以便在 ServiceC#methodC() 抛出异常时(或任何抛出异常的调用) -- ServiceAServiceB).

我试图通过 REQUIRED 传播使 Main#outerMethod 具有事务性,但似乎数据库提交没有被回滚。我什至用 rollbackFor 指定了特定的 类 但提交仍然存在。有谁知道如何解决这个问题?

由于没有提供代码,所以很难确定。 但是,事务仅在方法为 public 时才有效。私有方法未被代理,因此不存在对它们的事务支持。

通读 Declarative Transations - Spring Docs 了解更多详情。

如果您仍在努力获得更好的帮助,请post编码。

我为了让它工作所做的是将 ServiceB.methodB()ServiceC.methodC() 调用迁移到 ServiceA.methodA(),并使 methodA() @Transactional 同时抛出我所有的来自 methodA() 的异常和基于这三个异常的回滚(我的逻辑实际上允许我这样做):

@Component
public class Main implements RPCInterface {

  @Autowired
  private ServiceA serviceA;

  @Override
  public void outerMethod() throws ExceptionO {

    try {
      serviceA.methodA();

    } catch (ExceptionOne e) {
      throw new ExceptionO(e.getMessage, e);
    } catch (ExceptionTwo e) {
      throw new ExceptionO(e.getMessage, e);
    } catch (ExceptionThree e) {
      throw new ExceptionO(e.getMessage, e);
    }
  }
}

@Service
public class ServiceA implements SA {

  @Autowired
  private ServiceA1 serviceA1;

  @Autowired
  private ServiceB serviceB;

  @Autowired
  private ServiceC serviceC;

  @Override
  @Transactional (value="txManager", propagation=Propagation.REQUIRED, rollbackFor={ExceptionOne.class, ExceptionTwo.class, ExceptionThree.class})
  public void methodA() throw ExceptionOne, ExceptionTwo, ExceptionThree {
    serviceA1.methodA1();
    serviceB.methodB();
    serviceC.methodC();
  }
}

@Service
public class ServiceA1 implements SA1 {
  @Autowired
  private ServiceDBTable1 serviceDBTable1;

  @Autowired
  private ServiceA1A serviceA1A;

  @Transactional
  @Override
  public void methodA1() {
    serviceDBTable4.callToMapper4();
    serviceA1A.methodA1A();
  }
}

@Service
@Transactional (value="txManager", propagation=Propagation.REQUIRED)
public class ServiceA1A implements SA1A {

  @Autowired
  private ServiceDBTable2 serviceDBTable2;

  @Override
  public void methodA1A() {
    serviceDBTable1.callToMapper1();
  }
}

@Service
public class ServiceB implements SB {

  @Autowired
  private ServiceDBTable3 serviceDBTable3;

  @Override
  @Transactional (value="txManager", propagation=Propagation.REQUIRED)
  public void methodB() {
    serviceDBTable3.callToMapper3();
  }
}

@Service
public class ServiceC implements SC {

  @Override
  public void methodC() throws ExceptionThree {
    // code that throws ExceptionThree
  }
}