복붙노트

[SPRING] Spring과 Hibernate를 사용하여 여러 데이터베이스에서 분산 트랜잭션을 수행하는 '최선의'방법은 무엇입니까?

SPRING

Spring과 Hibernate를 사용하여 여러 데이터베이스에서 분산 트랜잭션을 수행하는 '최선의'방법은 무엇입니까?

나는 구석에 앉아서 두 개의 서로 다른 데이터베이스를 주기적으로 업데이트하는 유틸리티와 같은 애플리케이션을 보유하고 있습니다.

Spring Application Context로 구축 된 작은 독립형 애플리케이션입니다. 컨텍스트에는 Spring에 구성된 Commons DBCP 데이터 소스를 사용하여 두 개의 Hibernate Session Factories가 구성되어 있습니다.

현재 트랜잭션 관리는 없지만 일부는 추가하려고합니다. 한 데이터베이스에 대한 업데이트는 다른 데이터베이스에 대한 업데이트에 따라 달라집니다.

이 응용 프로그램은 Java EE 컨테이너에 있지 않습니다.이 응용 프로그램은 쉘 스크립트에서 호출되는 정적 시작 관리자 클래스에 의해 부트 스트랩됩니다. 실행 프로그램 클래스는 Application Context를 인스턴스화 한 다음 Bean 중 하나에서 메소드를 호출합니다.

트랜잭션을 데이터베이스 업데이트와 관련시키는 '최선의'방법은 무엇입니까?

나는 당신에게 '최고'라는 정의를 남겨 두겠다.하지만 '설정하기 쉽다', '구성하기 쉽다', '저렴하다', '패키지하고 재배포하기 쉽다'등의 기능이 있어야한다고 생각한다. 당연히 FOSS가 좋을 것입니다.

해결법

  1. ==============================

    1.둘 이상의 데이터베이스에서 트랜잭션을 분배하는 가장 좋은 방법은 다음과 같습니다.

    둘 이상의 데이터베이스에서 트랜잭션을 분배하는 가장 좋은 방법은 다음과 같습니다.

    어떤 사람들은 당신을 XA로 안내 할 것이지만 XA (또는 Two Phase Commit)는 거짓말 (또는 시장 사람)입니다.

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

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

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

  2. ==============================

    2.컨텍스트에서 트랜잭션 관리자를 설정하십시오. Spring 문서에는 예제가 있으며 매우 간단합니다. 그런 다음 트랜잭션을 실행하려고 할 때 :

    컨텍스트에서 트랜잭션 관리자를 설정하십시오. Spring 문서에는 예제가 있으며 매우 간단합니다. 그런 다음 트랜잭션을 실행하려고 할 때 :

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

    더 많은 예제와 정보를 보려면 다음을 참조하십시오. Spring을 사용한 XA 트랜잭션

  3. ==============================

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

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

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

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

  4. ==============================

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

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

  5. ==============================

    5.분산 된 db 트랜잭션을 지원하는 Spring ChainedTransactionManager - http://docs.spring.io/spring-data/commons/docs/1.6.2.RELEASE/api/org/springframework/data/transaction/ChainedTransactionManager.html을 시도 할 수있다. 이것은 XA에 대한 더 나은 대안이 될 수 있습니다.

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

  6. from https://stackoverflow.com/questions/128377/what-is-the-best-way-to-do-distributed-transactions-across-multiple-databases by cc-by-sa and MIT license