2017-03-10 86 views
0

我有嵌套事務的下列服務佈局:回滾所有DB犯嵌套事務春季

@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指定了具體的類,但提交仍然存在。有誰知道如何解決這個問題?

+0

爲什麼不將innerMethodThree放入與innerMethod_1a和2a相同的事務? – Simon

+0

@Simon我該如何做到這一點?必須在1)和2)之後調用'innerMethodThree'。 – NuCradle

+0

設置@Transactional的outerMethod,不需要新的1A和2A – Simon

回答

1

我做了什麼,使其工作是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 
    } 
} 
0

由於沒有碼錶示這是很難知道。 但是,交易只在方法公開時纔有效。私有方法沒有被代理,因此對它們的事務支持不存在。

通過Declarative Transations - Spring Docs閱讀更多細節。

如果您仍然掙扎得到更好的幫助請張貼代碼。

+0

內部方法都是服務調用(一個服務/對象,調用另一個服務/對象),所以它們必須公開。問題是上述配置是否應該起作用。分散的代碼數量很難發佈實際的代碼,因此上面是精簡版。 – NuCradle