2017-03-10 5 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 
    } 
} 

(또는 해당 문제에 대해 예외를 throw하는 임의의 개체 - ServiceA 또는 ServiceB).

나는 REQUIRED 전파로 트랜잭션을 만들려고했지만 데이터베이스 커밋은 롤백되지 않는 것처럼 보입니다. 심지어 rollbackFor으로 특정 클래스를 지정했지만 커밋은 지속됩니다. 누구든지이 문제를 해결하는 방법을 알고 있습니까?

+0

innerMethodThree를 innerMethod_1a 및 2a와 동일한 트랜잭션에 넣지 않는 이유는 무엇입니까? – Simon

+0

@Simon 어떻게해야합니까? 'innerMethodThree'는 1)과 2) 이후에 호출되어야합니다. – NuCradle

+0

outerMethod에 @Transactional을 설정하고 1a와 2a에 대해 새 값을 요구하지 않습니다. – Simon

답변

1

그 세 가지 예외를 기반으로 methodA() 및 롤백에서 내 모든 예외를 던지는 동안 ServiceA.methodA()ServiceB.methodB()ServiceC.methodC() 통화를 마이그레이션 및 methodA()@Transactional을 만드는 것이 었습니다 (내 논리는 나를 실제로 그렇게 할 수) :

@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

코드가 없으므로 확실하게 알기가 어렵습니다. 그러나 트랜잭션은 메서드가 public 인 경우에만 작동합니다. 개인 메소드는 프록시 화되지 않으므로 트랜잭션 메소드가 지원되지 않습니다.

자세한 내용은 Declarative Transations - Spring Docs을 통해 읽습니다.

더 나은 도움을 얻기 위해 여전히 고심하고 있다면 코드를 게시하십시오. 내가 일하기 위해 무슨 짓을

+0

내부 메소드는 모두 서비스 호출 (하나의 서비스/객체, 다른 서비스/객체 호출)이므로 공용이어야합니다. 문제는 위의 구성이 작동해야하는지 또는 작동하지 않아야하는지 여부입니다. 흩어져있는 코드의 양은 실제 코드를 게시하는 것을 어렵게하므로 위의 압축 버전입니다. – NuCradle