2017-03-10 4 views
0
にネストされたトランザクションでコミット

I持つネストされたトランザクションの次のサービスレイアウト:私はServiceC#methodC()が例外をスローした場合、すべてのDBがServiceAServiceBネストされた呼び出しの中にロールバックする呼び出しを行う必要があるロールバックすべての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 
    } 
} 

(または例外をスローするそのようなもののいずれか - ServiceAまたはServiceB)。

私はMain#outerMethodとトランザクションをREQUIREDと伝えようとしましたが、データベースコミットがロールバックされていないようです。私はrollbackForで特定のクラスを指定しましたが、コミットは持続します。誰もこの問題を解決する方法を知っていますか?

+0

なぜinnerMethodThreeをinnerMethod_1aと2aと同じトランザクションに入れないのですか? – Simon

+0

@サイモンどのように私はそれを達成するのですか? 'innerMethodThree'は1)と2)の後に呼び出さなければなりません。 – NuCradle

+0

outerMethodに@Transactionalを設定し、1aと2aのためにnewを必要としません。 – Simon

答えて

1

(私のロジックは、実際に私はそれを行うために許可):

@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から読んでください。

まだ改善のために苦労している場合は、コードを投稿してください。私はそれが仕事がServiceA.methodA()からServiceB.methodB()ServiceC.methodC()呼び出しを移行すると、これら3つの例外に基づいてmethodA()とロールバックからすべての私の例外を投げながらmethodA()@Transactionalを作ることだった作るためにやった

+0

内部メソッドはすべてサービスコール(1つのサービス/オブジェクト、別のサービス/オブジェクトを呼び出す)なので、パブリックにする必要があります。問題は、上記の設定がうまくいくべきかどうかです。散らばったコードの量は、実際のコードを投稿するのを難しくします。 – NuCradle

関連する問題