15 de agosto de 2026 • Java

11 - Anotação Transacional Spring

Tabela de Conteúdo

  1. Introdução
  2. O que é uma Transação?
  3. Princípios ACID
  4. Contexto Transacional
  5. Gerenciadores de Transações
  6. Spring @Transactional
  7. Comportamento de Rollback
  8. Propagação de Transações
  9. Níveis de Isolamento
  10. Timeouts de Transação
  11. Transações Somente Leitura
  12. Como o Spring Implementa Transações
  13. Limitações de @Transactional
  14. Vantagens e Desvantagens
  15. Melhores Práticas
  16. Resumo

Introdução

Em aplicações corporativas, a consistência dos dados é crítica.

Considere as seguintes operações:

  • Transferências de dinheiro
  • Criação de pedidos
  • Atualizações de estoque
  • Processamento de pagamentos

Se uma aplicação falhar no meio dessas operações, os dados podem se tornar inconsistentes.

Para resolver este problema, bancos de dados relacionais implementam transações, e o Spring fornece a anotação @Transactional para gerenciá-las automaticamente.


O que é uma Transação?

Uma transação é uma unidade lógica de trabalho que consiste em uma ou mais operações executadas como uma única unidade indivisível.

Uma transação tem apenas dois resultados possíveis:

  • Commit → salva permanentemente todas as alterações.
  • Rollback → desfaz todas as alterações.

Exemplo

Transferência bancária:

accountA.debit(100);
accountB.credit(100);

Ambas as operações devem ser bem-sucedidas juntas.

Se uma operação falhar:

Rollback de Tudo

Princípios ACID

ACID é um conjunto de propriedades que garantem a confiabilidade da transação.

A — Atomicidade

Uma transação é tudo-ou-nada.

Exemplo

accountA.debit(100);
accountB.credit(100);

Se a segunda operação falhar:

Rollback

Resultado:

Nenhuma alteração persistida

Benefício

Previne atualizações parciais.


C — Consistência

Uma transação deve mover o banco de dados de um estado válido para outro estado válido.

Exemplo

Regra de negócio:

balance >= 0

Esta operação é inválida:

account.setBalance(-500);

Resultado:

Transação Rejeitada

Benefício

Mantém regras e restrições de negócio.


I — Isolamento

Transações concorrentes não devem interferir umas nas outras.

Exemplo

Quantidade em estoque:

Estoque = 1

Dois usuários compram simultaneamente.

Sem isolamento:

Estoque = -1

Com isolamento adequado:

Estoque = 0

Benefício

Previne problemas de concorrência.


D — Durabilidade

Uma vez realizado o commit, os dados sobrevivem a falhas.

Exemplos:

  • Reinicialização do servidor
  • Queda de energia
  • Falha da aplicação
COMMIT;

Após o commit:

Dados são armazenados permanentemente

Benefício

Garante persistência.


Contexto Transacional

O que é um Contexto Transacional?

Um contexto transacional é o escopo de execução no qual todas as operações de banco de dados participam da mesma transação.

Quando o Spring inicia uma transação:

Contexto Transacional Criado

Todas as operações de repositório executadas dentro desse contexto compartilham:

  • Mesma transação
  • Mesma conexão
  • Mesmo commit
  • Mesmo rollback

Exemplo

@Service
public class UserService {

    @Transactional
    public void createUser() {

        userRepository.save(user);

        roleRepository.save(role);

        auditRepository.save(log);
    }
}

Execução:

Contexto Transacional
    ├── userRepository.save()
    ├── roleRepository.save()
    └── auditRepository.save()

Se qualquer operação falhar:

Rollback de Tudo

Por que é Importante?

Sem um contexto transacional:

Operação 1 → Commit
Operação 2 → Falha
Operação 3 → Nunca Executa

Resultado:

Dados Inconsistentes

Gerenciadores de Transações

O que é um Gerenciador de Transações?

O Gerenciador de Transações é responsável por:

  • Iniciar transações
  • Realizar commit de transações
  • Realizar rollback de transações

O Spring delega o gerenciamento de transações a um PlatformTransactionManager.


PlatformTransactionManager

Interface de transação principal do Spring:

public interface PlatformTransactionManager {
}

O Spring seleciona automaticamente a implementação apropriada.


JpaTransactionManager

Usado com:

  • JPA
  • Hibernate
  • Spring Data JPA
@Bean
public PlatformTransactionManager transactionManager(
        EntityManagerFactory emf) {

    return new JpaTransactionManager(emf);
}

DataSourceTransactionManager

Usado com:

  • JDBC
  • JdbcTemplate
@Bean
public PlatformTransactionManager transactionManager(
        DataSource ds) {

    return new DataSourceTransactionManager(ds);
}

JtaTransactionManager

Usado para transações distribuídas.

Exemplos:

  • Múltiplos bancos de dados
  • Banco de dados + Mensageria
  • Transações XA

Fluxo da Transação

@Transactional

Proxy AOP do Spring

PlatformTransactionManager

Banco de Dados

Spring @Transactional

O que é @Transactional?

@Transactional é uma anotação do Spring que define limites transacionais.

O Spring automaticamente:

  1. Abre uma transação.
  2. Executa o método.
  3. Realiza commit em caso de sucesso.
  4. Realiza rollback em caso de falha.

Exemplo

@Service
public class TransferService {

    @Transactional
    public void transfer() {

        accountA.debit(100);

        accountB.credit(100);
    }
}

Execução:

Abrir Transação

Débito

Crédito

Commit

Falha:

Abrir Transação

Débito

Exceção

Rollback

Transação no Nível da Classe

@Service
@Transactional
public class OrderService {

    public void createOrder() {}

    public void cancelOrder() {}
}

Todos os métodos públicos tornam-se transacionais.


Comportamento de Rollback

Regras Padrão de Rollback

O Spring faz rollback automaticamente para:

RuntimeException
Error

Exemplo:

@Transactional
public void process() {

    throw new RuntimeException();
}

Resultado:

Rollback

Exceções Verificadas

Exceções verificadas (Checked Exceptions) requerem configuração explícita.

@Transactional(
    rollbackFor = Exception.class
)
public void process() throws Exception {

    throw new Exception();
}

Resultado:

Rollback

Propagação de Transações

A propagação define como um método transacional se comporta quando outra transação já existe.


REQUIRED (Padrão)

@Transactional(
    propagation = Propagation.REQUIRED
)

Comportamento:

Transação Existente?
    Sim → Juntar-se
    Não → Criar Nova

Mais comumente usado.


REQUIRES_NEW

@Transactional(
    propagation = Propagation.REQUIRES_NEW
)

Comportamento:

Suspender Transação Atual
Criar Nova Transação
Executar
Commit
Retomar Transação Original

Casos de uso comuns:

  • Logs de auditoria
  • Notificações
  • Histórico de eventos

SUPPORTS

@Transactional(
    propagation = Propagation.SUPPORTS
)

Comportamento:

Transação Existe?
    Sim → Juntar-se
    Não → Executar Sem Transação

Comum para operações de leitura.


NOT_SUPPORTED

@Transactional(
    propagation = Propagation.NOT_SUPPORTED
)

Comportamento:

Suspender Transação Existente
Executar Sem Transação
Retomar Transação

Útil para:

  • Chamadas de API externas
  • Tarefas de longa duração

MANDATORY

@Transactional(
    propagation = Propagation.MANDATORY
)

Requer uma transação existente.

Caso contrário:

IllegalTransactionStateException

NEVER

@Transactional(
    propagation = Propagation.NEVER
)

Falha se uma transação existir.


NESTED

@Transactional(
    propagation = Propagation.NESTED
)

Cria savepoints.

Transação Pai

      ├── Savepoint

      └── Transação Aninhada

Permite rollback parcial.

O suporte do banco de dados varia.


Níveis de Isolamento

Os níveis de isolamento determinam como transações concorrentes interagem.


Problemas de Concorrência

Leitura Suja (Dirty Read)

Leitura de dados não confirmados.

T1 Atualiza Valor
T2 Lê Valor
T1 Faz Rollback

T2 leu dados inválidos.


Leitura Não Repetível (Non-Repeatable Read)

Ler a mesma linha duas vezes retorna valores diferentes.

T1 Lê Salário = 1000

T2 Atualiza Salário = 2000

T1 Lê Novamente = 2000

Leitura Fantasma (Phantom Read)

Uma consulta retorna linhas adicionais.

SELECT * FROM employees

Outra transação insere novas linhas.

A segunda consulta retorna resultados diferentes.


READ_UNCOMMITTED

Permite:

  • Leituras Sujas
  • Leituras Não Repetíveis
  • Leituras Fantasmas
@Transactional(
    isolation = Isolation.READ_UNCOMMITTED
)

Maior desempenho, menor consistência.


READ_COMMITTED

Previne:

  • Leituras Sujas

Permite:

  • Leituras Não Repetíveis
  • Leituras Fantasmas
@Transactional(
    isolation = Isolation.READ_COMMITTED
)

Mais comumente usado.


REPEATABLE_READ

Previne:

  • Leituras Sujas
  • Leituras Não Repetíveis

Permite:

  • Leituras Fantasmas
@Transactional(
    isolation = Isolation.REPEATABLE_READ
)

Padrão no MySQL InnoDB.


SERIALIZABLE

Previne:

  • Leituras Sujas
  • Leituras Não Repetíveis
  • Leituras Fantasmas
@Transactional(
    isolation = Isolation.SERIALIZABLE
)

Maior consistência.

Compromissos:

  • Mais locks
  • Menor throughput

Tabela Comparativa de Isolamento

Nível de IsolamentoLeitura SujaLeitura Não RepetívelLeitura Fantasma
READ_UNCOMMITTED❌ Permitido❌ Permitido❌ Permitido
READ_COMMITTED✅ Prevenido❌ Permitido❌ Permitido
REPEATABLE_READ✅ Prevenido✅ Prevenido❌ Permitido
SERIALIZABLE✅ Prevenido✅ Prevenido✅ Prevenido

Timeouts de Transação

O que é um Timeout?

Define a duração máxima de uma transação.


Exemplo

@Transactional(timeout = 10)
public void processOrder() {
}

Significado:

Duração Máxima = 10 Segundos

Se excedido:

TransactionTimedOutException
Rollback

Por que Usar Timeouts?

Previne:

  • Transações de longa duração
  • Esgotamento de recursos
  • Contenção de locks
  • Deadlocks

Transações Somente Leitura

O que é uma Transação Somente Leitura?

Usado quando não são esperadas modificações de dados.

@Transactional(readOnly = true)
public User findUser(Long id) {
    return repository.findById(id).orElseThrow();
}

Benefícios

Otimização do Hibernate

Fluxo normal:

Carregar Entidade

Rastrear Alterações

Flush

Somente leitura:

Carregar Entidade

Sem Dirty Checking

Melhor Desempenho

Útil para:

@Transactional(readOnly = true)
public List<User> findAllUsers() {
    return repository.findAll();
}

Benefícios:

  • Menos memória
  • Menos CPU
  • Execução mais rápida

Nota Importante

Somente leitura nem sempre impede fisicamente as escritas.

O comportamento depende de:

  • Banco de dados
  • Driver JDBC
  • Gerenciador de Transações

Como o Spring Implementa Transações

O Spring usa:

  • AOP (Programação Orientada a Aspectos)
  • Proxies Dinâmicos

Fluxo Interno

Cliente

Proxy do Spring

Abrir Transação

Executar Método

Commit / Rollback

Lógica equivalente:

beginTransaction();

try {
    businessMethod();
    commit();
}
catch(Exception ex) {
    rollback();
}

Limitações de @Transactional

Métodos Privados

Não funciona.

@Transactional
private void save() {}

Razão:

Proxy Não Consegue Interceptar Métodos Privados

Auto Invocação

Não funciona.

@Service
public class UserService {

    public void methodA() {
        methodB();
    }

    @Transactional
    public void methodB() {
    }
}

Razão:

Chamada Ignora o Proxy do Spring

Vantagens

Simplicidade

@Transactional
public void save() {}

Menos Código Repetitivo

Não há necessidade de:

beginTransaction();
commit();
rollback();

Integração Transparente

Funciona com:

  • JPA
  • Hibernate
  • JDBC
  • Spring Data

Melhor Consistência

Ajuda a aplicar os princípios ACID.


Desvantagens

Transações Longas Podem Ser Perigosas

Pode causar:

  • Locks
  • Deadlocks
  • Degradação de desempenho

Chamadas Externas Dentro de Transações

Exemplo ruim:

@Transactional
public void process() {

    externalApi.call();

    repository.save(entity);
}

A transação permanece aberta durante a chamada externa.


Curva de Aprendizagem

Desenvolvedores devem entender:

  • Propagação
  • Isolamento
  • Regras de rollback
  • Comportamento do proxy

Melhores Práticas

✅ Coloque @Transactional na camada de Serviço.

✅ Mantenha as transações curtas.

✅ Use readOnly = true sempre que possível.

✅ Evite chamadas remotas dentro de transações.

✅ Entenda a propagação antes de usar REQUIRES_NEW.

✅ Use timeouts para processos de longa duração.

❌ Não coloque @Transactional em Controllers.

❌ Não crie escopos transacionais grandes.

❌ Não ignore as implicações do nível de isolamento.


Resumo

TópicoPropósito
TransaçãoUnidade de trabalho
ACIDGarantias de confiabilidade
Contexto TransacionalEscopo transacional compartilhado
Gerenciador de Trans.Controla o ciclo de vida da transação
@TransactionalGerenciamento de transações declarativo
PropagaçãoRegras de interação de transações
IsolamentoControle de concorrência
TimeoutDuração máxima da transação
Somente LeituraOtimização de consultas
Proxy AOPMecanismo de transação do Spring

Compreender esses conceitos é essencial para construir aplicações Spring confiáveis, escaláveis e consistentes. Juntos, os princípios ACID, gerenciadores de transações, regras de propagação, níveis de isolamento e a anotação @Transactional formam a base do gerenciamento de transações no Spring Framework e Spring Boot.

← Voltar para o blog