O que é a 'melhor' maneira de fazer transações distribuídas em vários bancos de dados usando Spring e Hibernate

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

Pergunta

Eu tenho um aplicativo - mais como um utilitário - que se senta em um canto e atualizações de duas bases de dados diferentes periodicamente.

É um pequeno aplicativo autônomo que foi construída com um contexto de aplicativo Spring. O contexto tem duas fábricas de sessão de hibernação configurados em que, por sua vez, utilizando as fontes de dados Commons DBCP configurados na Primavera.

Atualmente, não há gerenciamento de transações, mas eu gostaria de adicionar algum. A atualização de um banco de dados depende de uma atualização bem-sucedida para o outro.

O aplicativo não se sentar em um container Java EE - é bootstrapped por uma classe lançador estática chamado de um script shell. A classe lançador instancia o contexto do aplicativo e, em seguida, chama um método em um de seus grãos.

O que é a 'melhor' maneira de colocar transacionalidade em torno das atualizações de banco de dados?

Vou deixar a definição de 'melhor' para você, mas eu acho que deveria haver alguma função de 'fácil de configurar', 'fácil de configurar', 'barato' e 'fácil de pacote e redistribuir'. Naturalmente FOSS seria bom.

Foi útil?

Solução

A melhor maneira de distribuir transações por mais de um banco de dados é:. Do not

Algumas pessoas vão apontar-lhe XA mas XA (ou duas fases) é uma mentira (ou marketese).

Imagine-: Após a primeira fase já disse o gerente XA que ele pode enviar cometer o final, a conexão de rede a um dos bancos de dados falhar. O que agora? Tempo esgotado? Isso deixaria o outro banco de dados corrompido. Reversão? Dois problemas: Você não pode reverter a cometer e como você sabe o que aconteceu com o segundo banco de dados? Talvez a conexão de rede falhou depois de confirmada com êxito os dados e somente a mensagem de "sucesso" foi perdido?

A melhor maneira é para copiar os dados em um único lugar. Use um esquema que lhe permite interromper a cópia e continuá-lo a qualquer momento (por exemplo, ignorar os dados que você já tem ou condenar a escolha pela ID e solicitar apenas registros> MAX (ID) da sua cópia). Proteja isso com uma transação. Este não é um problema desde que você está lendo apenas os dados a partir da fonte, por isso, quando a transação falhar por qualquer motivo, você pode ignorar o banco de dados fonte. Portanto, esta é uma transação única fonte velha lisa.

Depois de ter copiado os dados, processá-lo localmente.

Outras dicas

Configuração de um gerenciador de transações em seu contexto. docs Primavera tem exemplos, e é muito simples. Então, quando você quer executar uma transação:

try { 
    TransactionTemplate tt = new TransactionTemplate(txManager);

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

Para obter mais exemplos e informações talvez olhar para isto: transações XA utilizando Spring

Quando você diz "duas bases de dados diferentes", que quer dizer com servidores de banco de dados diferentes, ou dois esquemas diferentes dentro do mesmo servidor DB?

Se o primeiro, então se você quiser transacionalidade cheio, então você precisa da API transação XA, que fornece completa duas fases. Mas o mais importante, você também precisa de uma transação coordenador / monitor de que administra a propagação de transação entre os diferentes sistemas de banco de dados. Isso faz parte do JavaEE spec, e uma parte muito rarefeita de isso mesmo. O coordenador TX em si é uma peça complexa de software. O seu software aplicativo (via Primavera, se assim o desejar) fala com o coordenador.

Se, no entanto, você significa apenas dois bancos de dados no mesmo servidor DB, então baunilha transações JDBC deve funcionar muito bem, apenas executar suas operações contra os dois bancos de dados em uma única transação.

Neste caso, você precisaria de um Monitor de Transação (suportar o servidor de protocolo XA) e certificar-se de seus bancos de dados suporta XA também. A maioria (? Todos) servidores J2EE vem com Transaction Monitor de construído em Se o seu código não está em execução no servidor J2EE, em seguida, há um grupo de alternativas independentes -. Atómicos, Bitronix, etc

.

Você poderia tentar Primavera ChainedTransactionManager - http://docs.spring.io/spring-data/commons/docs/1.6.2.RELEASE/api/org/springframework/data/transaction/ChainedTransactionManager.html que suportes distribuído transação db. Esta poderia ser uma alternativa melhor para XA

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top