Obtendo events de um database

Não estou muito familiarizado com os bancos de dados e o que eles oferecem fora das operações CRUD.

Minha pesquisa me levou a gatilhos . Basicamente, parece que os gatilhos oferecem esse tipo de funcionalidade:

(da Wikipedia )

Normalmente, há três events desencadeadores que fazem com que os acionadores “disparem”:

  • Evento INSERT (como um novo registro está sendo inserido no database).
  • Evento UPDATE (como um registro está sendo alterado).
  • Evento DELETE (como um registro está sendo excluído).

Minha pergunta é: existe alguma maneira de eu ser notificado em Java (preferencialmente incluindo os dados que foram alterados) pelo database quando um registro é Atualizado / Excluído / Inserido usando algum tipo de semântica de acionador?

Quais podem ser algumas soluções alternativas para esse problema? Como posso ouvir events de database?

A principal razão que eu quero fazer isso é um cenário como este :

Eu tenho 5 aplicativos cliente, todos em diferentes processos / existentes em diferentes PCs. Todos eles compartilham um database comum (Postgres, neste caso).

Digamos que um cliente altere um registro no database no qual todos os 5 clientes estejam “interessados”. Estou tentando pensar em maneiras para os clientes serem “notificados” da alteração (de preferência com os dados afetados anexados) em vez de eles consultando os dados em algum intervalo.

Usando o Oracle, você pode configurar um Trigger em uma tabela e depois fazer com que o gatilho envie uma mensagem JMS. O Oracle possui duas implementações diferentes do JMS. Você pode então ter um processo que “escute” a mensagem usando o Driver JDBC. Eu usei esse método para empurrar as alterações para o meu aplicativo vs. polling. Se você estiver usando um database Java (H2), terá opções adicionais. No meu aplicativo atual (SIEM), tenho gatilhos em H2 que publicam events de mudança usando o JMX.

Não misture o database (que contém os dados) e os events nesses dados.

Triggers são unidirecionais, mas normalmente você terá uma camada de persistência em seu aplicativo. Essa camada pode escolher triggersr events quando certas coisas acontecem – digamos, para um tópico do JMS.

Triggers são uma última coisa, como você está operando em itens relacionais, em vez de “events” nos dados. (Por exemplo, uma “atualização” poderia, na verdade, mapear para um evento “company changed legal name”) Se você confiar no db, terá que mapear as inserções e atualizações de volta para events da vida real … que você já sabia!

Você pode, então, sobrepor outras coisas sobre essas notifications, como o processamento de stream de events, para localizar events nos quais outras pessoas estão interessadas.

James

Hmm. Então você está usando o PostgreSQL e quer “ouvir” events e ser “notificado” quando eles ocorrem?

http://www.postgresql.org/docs/8.3/static/sql-listen.html http://www.postgresql.org/docs/8.3/static/sql-notify.html

Espero que isto ajude!

Chamar processos externos do database é muito específico do fornecedor.

Apenas fora do topo da minha cabeça:

  • SQLServer pode chamar programas CLR de gatilhos,

  • postgresql pode chamar funções C arbitrárias carregadas dinamicamente,

  • O MySQL pode chamar funções C arbitrárias, mas elas devem ser compiladas,

  • O Sybase pode fazer chamadas ao sistema se configurado para isso.

A coisa mais simples a fazer é fazer com que os gatilhos insert / update / delete façam uma input em alguma tabela de log e fazer com que seu programa java monitore essa tabela. Boas colunas para ter em sua tabela de log seria coisas como EVENT_CODE, LOG_DATETIME e LOG_MSG.

A menos que você exija um desempenho muito alto ou precise manipular 100.000 registros, isso provavelmente é suficiente.

Eu acho que você está confundindo duas coisas. Ambos são altamente específicos do fornecedor de db.

O primeiro eu chamarei de “gatilhos”. Tenho certeza de que há pelo menos um fornecedor de database que acha que os gatilhos são diferentes disso, mas tenha paciência comigo. Um acionador é um código do lado do servidor que pode ser anexado à tabela. Por exemplo, você poderia executar um procedimento armazenado PSQL em cada atualização na tabela X. Alguns bancos de dados permitem que você os escreva em linguagens de programação reais, outros apenas em sua variante do SQL. Os gatilhos normalmente são razoavelmente rápidos e escalonáveis.

O outro eu chamarei de “events”. Esses são triggersdores que são triggersdos no database que permitem definir um manipulador de events em seu programa cliente. IE, sempre que houver atualizações no database de clientes, acesse updateClientsList em seu programa. Por exemplo, usando python e firebird, consulte http://www.firebirdsql.org/devel/python/docs/3.3.0/beyond-python-db-api.html#database-event-notification

Eu acredito que a sugestão anterior para usar um monitor é uma maneira equivalente de implementar isso usando algum outro database. Talvez oráculo? Os serviços de notificação do MSSQL, mencionados em outra resposta, também são outra implementação disso.

Eu diria que é melhor você REALMENTE saber por que você quer que o database notifique o programa do seu cliente, caso contrário você deve ficar com os gatilhos do lado do servidor.

O que você está pedindo completamente depende do database que você está usando e da estrutura que você está usando para se comunicar com seu database.

Se você está usando algo como o Hibernate como sua camada de persistência, ele tem um conjunto de ouvintes e interceptores que você pode usar para monitorar os registros que entram e saem do database.

Existem algumas técnicas diferentes aqui, dependendo do database que você está usando. Uma ideia é pesquisar o database (o que, com certeza, você está tentando evitar). Basicamente, você pode verificar as alterações de vez em quando.

Outra solução (se você estiver usando o SQL Server 2005) é usar o Notification Services, embora essa tecnologia esteja supostamente sendo substituída no SQL 2008 (ainda não vimos uma substituição pura, mas a Microsoft falou sobre isso publicamente).

Se você estiver usando o Oracle, confira este post anterior .

Geralmente é para isso que serve a aplicação cliente / servidor padrão. Se todas as inserções / atualizações / exclusões passarem pelo aplicativo do servidor, que então modifica o database, os aplicativos clientes poderão descobrir muito mais facilmente quais alterações foram feitas.

Se você estiver usando o postgresql, ele terá capacidade de receber notifications do cliente JDBC.

Sugiro usar uma coluna de carimbo de data / hora, última atualização, junto com possivelmente o usuário atualizando o registro e, em seguida, permitir que os clientes verifiquem o registro de data e hora do registro local em relação ao registro persistido.

A complexidade adicional de adicionar uma funcionalidade callback / trigger simplesmente não vale a pena na minha opinião, a menos que seja suportada pelo backend do database e pela biblioteca cliente usada, como por exemplo os serviços de notificação oferecidos pelo SQL Server 2005 em conjunto com o ADO.NET.

Intereting Posts