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

标签 java spring nested rollback spring-transactions

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

@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
  }
}

ServiceC#methodC() 抛出异常时,我需要在 ServiceAServiceB 嵌套调用中进行所有数据库调用以回滚(或其中任何抛出异常的项 - ServiceAServiceB)。

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

最佳答案

为了使其正常工作,我所做的是将 ServiceB.methodB()ServiceC.methodC() 调用迁移到 ServiceA.methodA() code>,并创建 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
  }
}

关于java - 在 Spring 中回滚嵌套事务中的所有数据库提交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42708516/

相关文章:

java - 接受字符串文本并返回已识别整数之和的方法

java - 用于传输文件的 jboss Web 服务

Spring Mongodb 双向 dbref

spring - 使用 Apache poi 将 csv 转换为 xls/xlsx?

javascript - 升级到 Spring 4.3.0,静态 JS 文件现在作为 'application/octet-stream' 而不是 Spring 4.2.6 中的 'application/javascript'

json - 在 SWIFT 4 中解析嵌套的 JSON

python:以灵活的方式处理深度嵌套数据的有效技术是什么?

java - 关于 JPQL 的困惑

java - rabbitmq交换路由 key 意外匹配

mysql - SQL:哪个国家的城市最多?