스프링 및 최대 절전 모드를 사용하여 여러 데이터베이스에서 분산 트랜잭션을 수행하는 '가장 좋은'방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/128377

문제

구석에 위치하고 두 개의 다른 데이터베이스를 주기적으로 업데이트하는 응용 프로그램이 있습니다.

스프링 애플리케이션 컨텍스트로 구축 된 작은 독립형 앱입니다. 컨텍스트에는 두 개의 최대 절전 모드 세션 공장이 구성되어 있으며, 봄에 구성된 Commons DBCP 데이터 소스를 사용하여 구성됩니다.

현재 거래 관리는 없지만 일부를 추가하고 싶습니다. 한 데이터베이스에 대한 업데이트는 다른 데이터베이스에 대한 성공적인 업데이트에 따라 다릅니다.

이 앱은 Java EE 컨테이너에 앉아 있지 않습니다. 쉘 스크립트에서 호출 된 정적 런처 클래스로 부트 스트랩됩니다. 런처 클래스는 응용 프로그램 컨텍스트를 인스턴스화 한 다음 콩 중 하나에서 메소드를 호출합니다.

데이터베이스 업데이트에 거래를하는 '가장 좋은'방법은 무엇입니까?

나는 당신에게 '최고'의 정의를 남겨 두지 만 '쉽게 설정하기 쉬운', '쉽게 구성', '저렴한'및 '패키지 및 재분배가 쉬운'기능이어야한다고 생각합니다. 자연스럽게 포스가 좋을 것입니다.

도움이 되었습니까?

해결책

하나 이상의 데이터베이스에 거래를 배포하는 가장 좋은 방법은 다음과 같습니다.

어떤 사람들은 XA를 지적하지만 XA (또는 2 단계 커밋)는 거짓말 (또는 시장)입니다.

상상해보십시오 : 첫 번째 단계가 XA 관리자에게 최종 커밋을 보낼 수 있다고 말한 후에는 데이터베이스 중 하나에 대한 네트워크 연결이 실패합니다. 이제 뭐? 시간 초과? 그것은 다른 데이터베이스를 손상시킬 것입니다. 롤백? 두 가지 문제 : 커밋을 롤백 할 수 없으며 두 번째 데이터베이스에 무슨 일이 있었는지 어떻게 알 수 있습니까? 네트워크 연결이 데이터를 성공적으로 커밋 한 후에는 실패했으며 "성공"메시지 만 손실 되었습니까?

가장 좋은 방법은 데이터를 단일 장소에 복사하는 것입니다. 사본을 중단하고 언제든지 계속 사용할 수있는 체계를 사용하여 언제든지 (예 : 이미 가지고있는 데이터를 무시하거나 ID로 선택을 주문하고 사본의 최대 레코드> 최대 (ID)를 요청하십시오). 거래로 이것을 보호하십시오. 소스에서 데이터 만 읽기 때문에 문제가되지 않으므로 트랜잭션에 실패하면 소스 데이터베이스를 무시할 수 있습니다. 따라서 이것은 평범한 오래된 단일 소스 트랜잭션입니다.

데이터를 복사 한 후 로컬로 처리하십시오.

다른 팁

상황에서 트랜잭션 관리자를 설정하십시오. 스프링 문서에는 예제가 있으며 매우 간단합니다. 그런 다음 거래를 실행하려면 다음과 같습니다.

try { 
    TransactionTemplate tt = new TransactionTemplate(txManager);

    tt.execute(new TransactionCallbackWithoutResult(){
    protected void doInTransactionWithoutResult(
            TransactionStatus status) {
        updateDb1();
        updateDb2();
    }
} catch (TransactionException ex) {
    // handle 
}

더 많은 예와 정보를 보려면 아마도 다음을 살펴보십시오.Spring을 사용한 XA 거래

"두 개의 다른 데이터베이스"라고 말할 때, 동일한 DB 서버 내의 다른 데이터베이스 서버, 또는 두 개의 다른 스키마를 의미합니까?

전자의 경우 전체 트랜잭션을 원한다면 전체 2 단계 커밋을 제공하는 XA 트랜잭션 API가 필요합니다. 그러나 더 중요한 것은 다른 데이터베이스 시스템 간의 트랜잭션 전파를 관리하는 트랜잭션 코디네이터/모니터도 필요합니다. 이것은 Javaee Spec의 일부이며, 그것의 꽤 희귀 한 부분입니다. TX 코디네이터 자체는 복잡한 소프트웨어입니다. 응용 프로그램 소프트웨어 (Spring, 원하는 경우)가 코디네이터와 대화합니다.

그러나 동일한 DB 서버 내의 두 데이터베이스를 의미하는 경우 바닐라 JDBC 트랜잭션이 잘 작동하면 단일 트랜잭션 내에서 두 데이터베이스에 대해 작업을 수행해야합니다.

이 경우 트랜잭션 모니터 (서버 지원 XA 프로토콜)가 필요하고 데이터베이스가 XA를 지원하는지 확인하십시오. 대부분의 (모두?) J2EE 서버는 트랜잭션 모니터가 내장되어 있습니다. 코드가 J2EE 서버에 있지 않은 경우 Atomicos, Bitronix 등의 독립형 대안이 많이 있습니다.

Spring ChaintTransactionManager를 시도 할 수 있습니다. http://docs.spring.io/spring-data/commons/docs/1.6.2.release/api/org/springframework/data/transaction/chaindtransactionmanager.html 분산 된 DB 트랜잭션을 지원합니다. 이것은 XA에 대한 더 나은 대안이 될 수 있습니다

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top