2011-10-10 12 views
2

응용 프로그램 시작 중에 사용자 테이블을 저장소 (다른 DB)와 동기화해야합니다. Apache mod_jk가있는 Tomcat 노드가 두 개 있습니다. 그래서 둘 다 다시 시작할 때 이중 삽입과 이중 업데이트를합니다. 는 T1 T1이 T2는Java Hibernate + Oracle 11.2 Locking

때 T1의 수정을 확약 는 T2 T1이 T1 T2 인서트를 삽입 T2는 데이터 T1이 동일한 데이터를 수정 데이터를 T2를 수정 읽기 데이터를 읽기 시작 시작 : 것 같다 데이터 및 다음 T2 업데이트 손실 된 같은 데이터를 수정합니다. 물론 삽입 작업 중에 중복 된 부분이 있습니다. 동기화는 어떻게해야합니까?

  1. "select * for update"(예 :)를 사용하여 모든 테이블을 잠그고 두 개의 동기화를 수행 할 수 있다고 가정합니다. 하나는 가득 찼고 다른 하나는 비어 있습니다.
  2. 여기에 특수 테이블을 만들고 거기에 STATUS 열을 넣을 수 있습니다. 한 노드가 시작되면 STATUS 필드의 SELECT FOR UPDATE를 수행하고이를 "RUNNING"으로 변경합니다. 다른 트랜잭션이 STATUS를 읽을 때 "RUNNING"으로 설정된 경우 동기화를 수행하지 않습니다.

최상의 해결책은 무엇입니까? 다른 제안. 감사합니다.

답변

1

문제는 서버 시작이 응용 프로그램을 호스팅하는 데 둘 이상의 서버가 사용되는 경우 응용 프로그램 시작을 의미하지 않는다는 것입니다.

두 서버를 항상 동시에 시작하고 중지하려면 web.xml 파일의 config 매개 변수 또는 시스템 등록 정보를 통해 동기화 중 하나만 구성하면됩니다.

모든 서버를 독립적으로 시작하고 중지 할 수 있다면 시작할 때 아무것도하지 않고 응용 프로그램의 관리 유스 케이스로 구현하고 외부에서 필요할 때 실행할 수 있습니다.

+0

고마워요! 그러나 나는 시작시에 그것을 할 필요가 있습니다. 비즈니스에서 '동기화'버튼을 누르기를 원하지 않음))) – Nick

0

JB Nizet이 말했듯이 동기화를 수행하지 않도록 한 서버를 구성하십시오. 우리 프로젝트에서는 Spring profiles을 사용합니다.

어쨌든 비즈니스 키에 고유 색인을 정의한 경우 중복되지 않아야합니다. 최대 절전 모드에서 optimistic locking을 사용하여 Oracle의 손실 된 업데이트를 제거 할 수 있습니다. 트랜잭션은 특정 버전 (읽은 버전)을 업데이트하려고 시도하고 다른 트랜잭션이 새 버전 카운터로 업데이트하면 오류가 발생합니다.