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

时间:2017-03-10 01:23:08

标签: 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
  }
}

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

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

2 个答案:

答案 0 :(得分:1)

我所做的工作是将export const TAGS_INPUT_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TagsInputValueAccessor), multi: true }; @Directive({ selector: 'input[tagsinput]', providers: [TAGS_INPUT_VALUE_ACCESSOR] }) export class TagsInputValueAccessor implements ControlValueAccessor { onChange = (_: any) => { }; onTouched = () => { }; $elem: any; constructor(private _elRef: ElementRef) { this.$elem = jQuery(this._elRef.nativeElement); } writeValue(value: any): void { this.$elem.val(value).tagsinput('removeAll'); this.$elem.tagsinput('add', value); } ngAfterViewInit() { this.$elem.on('change', (x: any) => this.onChange(x.target.value)).tagsinput() } registerOnChange(fn: (_: any) => void): void { this.onChange = fn; } registerOnTouched(fn: () => void): void { this.onTouched = fn; } } ServiceB.methodB()电话转移到ServiceC.methodC(),并使ServiceA.methodA() methodA()同时抛弃我的所有例外情况@Transactional并基于这三个例外回滚(我的逻辑实际上允许我这样做):

methodA()

答案 1 :(得分:0)

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

阅读Declarative Transations - Spring Docs了解详情。

如果您仍在努力获得更好的帮助,请发布代码。