tl; dr - quebre as regras, se necessário. DDD não pode resolver todos os problemas; de fato, as idéias objetivas que ele fornece são bons conselhos e um bom começo, mas escolhas realmente ruins para alguns problemas de negócios. Considere uma dica de como fazer as coisas.
Para a questão de carregar todos os filhos (transação) com o pai (conta) - Parece que você encontrou o problema n + 1 (algo para o google) que muitos ORMs resolveram.
Você pode resolvê-lo carregando preguiçosamente os filhos (transação) - somente quando necessário.
Mas parece que você já sabe disso ao mencionar que pode usar um TransactionRepository para resolver o problema.
Para "ocultar" esses dados para que apenas a Conta possa usá-los, você nem precisa armazená-los onde mais ninguém gostaria de desserializá-los, como uma tabela relacional pública. Você pode armazená-lo com o 'documento' da conta em um banco de dados do documento. De qualquer maneira, se alguém se esforçasse o suficiente, ainda conseguiria ver os dados. E 'trabalhe' com isso. E quando você não está olhando, eles vão!
Portanto, você pode configurar permissões, mas precisa executar a 'conta' como um processo separado.
O que você realmente percebe aqui é que o DDD e o uso puro do modelo de objeto às vezes levam você de volta a um canto. Na verdade, é claro, você não precisa usar a 'composição' / raiz agregada para se beneficiar dos princípios de design do DDD. É apenas uma coisa que você pode usar quando tiver uma situação que se encaixe em suas restrições.
Alguém pode dizer 'não otimize cedo'. Aqui, nesse caso, porém, você sabe a resposta - haverá transações suficientes para atolar um método que manterá todas elas para sempre com a conta.
A resposta real é começar a levantar SOA. No meu local de trabalho, assistimos aos vídeos de computação distribuída da Udi Dahan e compramos o nServiceBus (apenas nossa opção). Crie um serviço para contas - com seu próprio processo, filas de mensagens, acesso a um banco de dados de relações que só ele pode ver e ... viola, você pode codificar instruções SQL no programa e até mesmo lançar alguns scripts de transação Cobol (brincadeira) é claro), mas seriamente tem mais separação de preocupações do que o snob OO / Java mais inteligente jamais poderia sonhar.
Eu recomendaria modelá-lo bem de qualquer maneira; você pode obter os benefícios da raiz agregada aqui sem os problemas, tratando o serviço como um contexto de mini-limite.
Isso tem uma desvantagem, é claro. Você não pode apenas RPC (serviço da web, SOAP ou REST) dentro e fora de serviços e entre eles ou obter um antipadrão de SOA chamado 'o nó' devido ao acoplamento temporal. Você precisa usar a inversão do padrão de comunicação, também conhecido como 'Pub-Sub', que é como manipuladores de eventos e criadores de eventos, mas (1) entre processos (que você pode colocar em máquinas separadas se estiverem sobrecarregadas).
o problema real é que você não deseja que um serviço precise obter dados de outro serviço para "bloquear" ou esperar - você precisa disparar e esquecer a mensagem e deixar que um manipulador em outro local do programa o pegue para concluir o processamento. Isso significa que você precisa fazer sua lógica de maneira diferente. O nServicebus automatiza o padrão 'saga' para ajudar com um pouco disso, mas no final, você precisa desenvolver um estilo de codificação diferente. Você ainda pode fazer tudo, apenas tem que fazer diferente!
O livro "SOA Patterns", de Arnon Rotem-Gal-Oz, responde a muitas perguntas sobre isso. Incluir o uso de 'padrão de serviço ativo' para replicar periodicamente dados de serviços externos para o seu próprio país quando surgir a necessidade (muitos RPC seriam necessários ou o link não é confiável / não é no ecossistema de publicação / assinatura).
Apenas para visualizar, as interfaces de usuário precisam fazer RPC nos serviços. Os relatórios são gerados a partir de um banco de dados de relatórios alimentado pelos bancos de dados dos serviços. Algumas pessoas dizem que os relatórios não são necessários e que o problema deve ser resolvido de outra maneira. Seja cético em relação a essa conversa.
No final, porém, nem todas as coisas podem ser classificadas adequadamente em um único serviço. O mundo não roda em código ravioli! Então você terá que quebrar as regras. Mesmo que você nunca precise, os novos desenvolvedores do projeto farão isso quando você o deixar. Mas não se preocupe, se você fizer o que puder, os 85% que seguem as regras tornarão um programa muito mais sustentável.
Uau, isso foi longo.