Skip to content

Corrigir gerenciamento transacional no DataProvider #17

@wallanpsantos

Description

@wallanpsantos

Título: Fix @Transactional placement - move to DataProvider layer
Labels: critical, transaction, clean-architecture
Prioridade: CRÍTICA

Problema Atual (Ponto 2 do Feedback):

  • @Transactional incorretamente no UseCaseConfig (configuração de beans)
  • Operações críticas não são atômicas
  • Outbox events fora de transação

Solução Proposta:

// ❌ REMOVER do UseCaseConfig
@Configuration
public class UseCaseConfig {
    @Bean
    // @Transactional <- REMOVER ISSO
    public DepositUseCase depositUseCase(...) {
        return new DepositUseCase(...);
    }
}

// ✅ MOVER para DataProvider
@Repository
@Transactional // <- AQUI é o lugar correto
public class TransactionalWalletService implements WalletRepository {
    
    @Transactional
    @Override
    public WalletTransaction deposit(String userId, Money amount) {
        // 1. Buscar wallet
        // 2. Atualizar saldo
        // 3. Salvar transação
        // 4. Salvar evento outbox
        // TUDO na mesma transação!
    }
    
    @Transactional
    @Override
    public List<WalletTransaction> transfer(String fromUserId, String toUserId, Money amount) {
        // Transferência atômica completa
    }
}

Tarefas:

  • Remover @transactional do UseCaseConfig

  • Criar TransactionalWalletService no dataprovider

    // wallet-dataprovider
    @Service
    @Transactional
    public class TransactionalWalletService {
        
        @Transactional
        public WalletTransaction executeDeposit(String userId, Money amount) {
            // Orquestra operação completa de forma transacional
            Wallet wallet = findWallet(userId);
            wallet.deposit(amount);
            Wallet saved = walletJpaRepository.save(wallet);
            
            WalletTransaction transaction = createTransaction(...);
            transactionJpaRepository.save(transaction);
            
            // Outbox na MESMA transação
            outboxRepository.save(createOutboxEvent(...));
            
            return transaction;
        }
    }
  • Adaptar Use Cases para chamar TransactionalService

    // wallet-core - SEM @Transactional
    public class DepositUseCase {
        private final TransactionalWalletService transactionalService;
        
        public WalletTransaction execute(String userId, Money amount) {
            validateBusinessRules(userId, amount);
            return transactionalService.executeDeposit(userId, amount);
        }
    }
  • Criar testes de rollback

  • Testes de concorrência simulando falhas

Arquivos afetados:

wallet-config/src/main/java/com/br/walletconfig/usecase/UseCaseConfig.java (REMOVER @Transactional)
wallet-dataprovider/
├── service/
│   └── TransactionalWalletService.java (NOVO - COM @Transactional)
wallet-core/usecase/ (ADAPTAR para usar TransactionalService)

Metadata

Metadata

Assignees

Labels

architectureAlteração na arquiteturacriticalAlta Prioridade

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions