Estou pensando em um projeto para migrar parte de nossa SOA baseada em WCF para um modelo de barramento de serviço (provavelmente nServiceBus) e usando alguns pub-sub básicos para obter a Separação de Consulta de Comando .
Não sou novo em SOA, nem mesmo em modelos de barramento de serviço, mas confesso que até recentemente meu conceito de "separação" estava limitado ao espelhamento e replicação de bancos de dados comuns. Ainda assim, sinto-me atraído pela idéia, porque ela parece fornecer todos os benefícios de um sistema eventualmente consistente , enquanto evita muitas das desvantagens óbvias (principalmente a falta de suporte transacional adequado).
Eu li muito sobre o assunto de Udi Dahan, que é basicamente o guru das arquiteturas ESB (pelo menos no mundo da Microsoft), mas uma coisa que ele diz realmente me intriga:
À medida que obtemos entidades maiores com mais campos, também temos mais atores trabalhando com essas mesmas entidades, e maior a probabilidade de que algo toque algum atributo delas a qualquer momento, aumentando o número de conflitos de simultaneidade.
[...]
Um elemento central do CQRS é repensar o design da interface do usuário para nos permitir capturar a intenção de nossos usuários, de modo que tornar o cliente preferido seja uma unidade de trabalho diferente para o usuário do que indicar que o cliente mudou ou que conseguiu casado. O uso de uma interface do usuário semelhante ao Excel para alterações de dados não captura a intenção, como vimos acima.
- Udi Dahan, CQRS esclarecido
Da perspectiva descrita na citação, é difícil argumentar com essa lógica. Mas parece ir contra o grão em relação aos SOAs. Uma SOA (e realmente serviços em geral) deve lidar com mensagens de granularidade grossa, de modo a minimizar as conversas na rede - entre muitos outros benefícios.
Percebo que as conversas na rede não são um problema quando você tem sistemas altamente distribuídos com boas filas de mensagens e nenhuma bagagem de RPC, mas não parece aconselhável descartar completamente o problema. Udi quase parece estar dizendo que toda alteração de atributo (ou seja, atualização de campo) deve ser seu próprio comando, o que é difícil de imaginar no contexto de um usuário que potencialmente atualiza centenas ou milhares de entidades e atributos combinados, como costuma acontecer com um servidor tradicional. serviço de internet.
Uma atualização em lote no SQL Server pode levar uma fração de segundo, dada uma boa consulta altamente parametrizada, parâmetro com valor de tabela ou inserção em massa em uma tabela de teste; o processamento de todas essas atualizações, uma de cada vez, é lento, lento, lento e o hardware do banco de dados OLTP é o mais caro de todos para aumentar / diminuir .
Existe alguma maneira de conciliar essas preocupações concorrentes? Estou pensando da maneira errada? Esse problema tem uma solução conhecida no mundo CQS / ESB?
Caso contrário, como alguém decide qual deve ser o "nível correto" de granularidade em um comando? Existe algum "padrão" que se possa usar como ponto de partida - como o 3NF nos bancos de dados - e apenas desviar quando o perfil cuidadoso sugerir um benefício de desempenho potencialmente significativo?
Ou isso é possivelmente uma daquelas coisas que, apesar de várias opiniões fortes serem expressas por vários especialistas, é realmente apenas uma questão de opinião?