Pular para o conteúdo principal

Capítulo 1: Configuração de Datasources

Introdução​

Sempre que sua aplicação Spring Boot interage com o banco de dados, ela utiliza uma conexão. Mas de onde vêm essas conexões? Como elas são gerenciadas? Esse é o papel do Datasource.


🎯 Objetivos do Capítulo​

Ao final deste capítulo, você saberá:

  1. ✅ O que é um Datasource e por que ele é importante
  2. ✅ Como o Spring Boot configura automaticamente as conexões
  3. ✅ Configurar o HikariCP (o pool padrão)
  4. ✅ Otimizar os parâmetros para produção
  5. ✅ Configurar múltiplos datasources

1. O que é um Datasource?​

Definição Simples​

Um Datasource é um objeto que fornece conexões para o banco de dados.

O Problema Sem Pool de Conexões​

// ❌ MÁ PRÁTICA: Nova conexão a cada requisição
public void getUser(Long id) {
Connection conn = DriverManager.getConnection(url, user, password);
// ... usar a conexão
conn.close();
}

Problemas:

  • Criar uma conexão = 500ms a 1s (muito lento!)
  • 100 usuários simultâneos = 100 conexões = banco saturado
  • Sem reutilização = desperdício de recursos

A Solução: Pool de Conexões​

// ✅ BOA PRÁTICA: Reutilizar conexões
public void getUser(Long id) {
Connection conn = dataSource.getConnection(); // ← Conexão do pool (< 1ms)
// ... usar a conexão
conn.close(); // ← Retorna ao pool (não é realmente fechada)
}

Vantagens:

  • Conexões pré-criadas = resposta instantânea
  • Reutilização = menos carga no banco
  • Limita o número máximo de conexões

2. HikariCP: O Pool Padrão​

Por que HikariCP?​

O Spring Boot utiliza o HikariCP (光 = "luz" em japonês) porque é:

  • 🚀 O mais rápido (benchmarks comprovados)
  • 💪 O mais confiável (usado por grandes empresas)
  • 🔧 Simples de configurar

Auto-Configuração Spring Boot​

Quando você adiciona uma dependência de banco de dados, o Spring Boot configura automaticamente o HikariCP:

<!-- pom.xml -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<!-- HikariCP é incluído automaticamente! -->
</dependency>

3. Configuração Básica​

Configuração Mínima (H2)​

# application.properties
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=

Configuração PostgreSQL​

# application.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.username=postgres
spring.datasource.password=secret

Configuração MySQL​

# application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=secret

4. Configuração Avançada do HikariCP​

Parâmetros Essenciais​

# application.properties

# Tamanho do pool
spring.datasource.hikari.minimum-idle=5 # Conexões mínimas mantidas
spring.datasource.hikari.maximum-pool-size=10 # Conexões máximas

# Timeouts
spring.datasource.hikari.connection-timeout=30000 # Tempo máx para obter uma conexão (30s)
spring.datasource.hikari.idle-timeout=600000 # Tempo antes de fechar uma conexão idle (10min)
spring.datasource.hikari.max-lifetime=1800000 # Vida útil máx de uma conexão (30min)

# Nome do pool (para logs)
spring.datasource.hikari.pool-name=MyAppPool

Visualização do Pool​

┌─────────────────────────────────────────────────────┐
│ HikariCP Pool │
│ │
│ minimum-idle=5 maximum-pool-size=10 │
│ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Conn1│ │Conn2│ │Conn3│ │Conn4│ │Conn5│ (idle) │
│ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ │
│ │
│ + 5 conexões adicionais se necessário │
│ │
│ connection-timeout=30s (espera máx se pool cheio) │
└─────────────────────────────────────────────────────┘

Formato YAML (Alternativa)​

# application.yml
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: postgres
password: secret
hikari:
minimum-idle: 5
maximum-pool-size: 10
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
pool-name: MyAppPool

5. Recomendações por Ambiente​

Desenvolvimento (H2)​

# application-dev.properties
spring.datasource.url=jdbc:h2:mem:devdb
spring.datasource.hikari.minimum-idle=2
spring.datasource.hikari.maximum-pool-size=5

# Console H2 ativado
spring.h2.console.enabled=true

Produção (PostgreSQL)​

# application-prod.properties
spring.datasource.url=jdbc:postgresql://db.server.com:5432/proddb
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.maximum-pool-size=50

# Sem console H2!
spring.h2.console.enabled=false

# Validação das conexões
spring.datasource.hikari.connection-test-query=SELECT 1

Fórmula para maximum-pool-size​

Regra prática:
maximum-pool-size = (número de CPUs * 2) + número de discos

Exemplo:
- Servidor com 4 CPUs e 1 disco SSD
- Pool size = (4 * 2) + 1 = 9 ≈ 10
dica

Não exagere no tamanho! Um pool muito grande pode degradar a performance pois o banco terá que gerenciar conexões demais ao mesmo tempo.


6. Configuração Multi-Datasources​

Caso de Uso​

Às vezes, uma aplicação precisa se conectar a múltiplos bancos de dados:

Configuração​

# application.properties

# Datasource primário (PostgreSQL)
spring.datasource.primary.url=jdbc:postgresql://localhost:5432/usersdb
spring.datasource.primary.username=postgres
spring.datasource.primary.password=secret
spring.datasource.primary.driver-class-name=org.postgresql.Driver

# Datasource secundário (MySQL)
spring.datasource.secondary.url=jdbc:mysql://localhost:3306/productsdb
spring.datasource.secondary.username=root
spring.datasource.secondary.password=secret
spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver

Configuração Java​

@Configuration
public class DataSourceConfig {

// Datasource primário
@Primary
@Bean(name = "primaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}

// Datasource secundário
@Bean(name = "secondaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
}

Uso com JPA​

// Configuração do EntityManager para Primary
@Configuration
@EnableJpaRepositories(
basePackages = "com.example.repository.users",
entityManagerFactoryRef = "primaryEntityManager",
transactionManagerRef = "primaryTransactionManager"
)
public class PrimaryDatabaseConfig {
// ... configuração
}

// Configuração do EntityManager para Secondary
@Configuration
@EnableJpaRepositories(
basePackages = "com.example.repository.products",
entityManagerFactoryRef = "secondaryEntityManager",
transactionManagerRef = "secondaryTransactionManager"
)
public class SecondaryDatabaseConfig {
// ... configuração
}

7. Monitoramento do Pool​

Via Actuator​

Adicione o Spring Boot Actuator para monitorar o pool:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
# application.properties
management.endpoints.web.exposure.include=health,metrics
management.endpoint.health.show-details=always

Métricas Disponíveis​

# Verificar o pool
GET /actuator/metrics/hikaricp.connections

# Conexões ativas
GET /actuator/metrics/hikaricp.connections.active

# Conexões em espera
GET /actuator/metrics/hikaricp.connections.pending

# Timeouts
GET /actuator/metrics/hikaricp.connections.timeout

Exemplo de Resposta​

{
"name": "hikaricp.connections.active",
"measurements": [
{
"statistic": "VALUE",
"value": 3.0
}
],
"availableTags": [
{
"tag": "pool",
"values": ["MyAppPool"]
}
]
}

8. Problemas Comuns e Soluções​

❌ Connection Timeout​

HikariPool-1 - Connection is not available, request timed out after 30000ms.

Causas:

  • Pool muito pequeno
  • Conexões não fechadas (vazamento)
  • Consultas muito lentas

Soluções:

# Aumentar o pool
spring.datasource.hikari.maximum-pool-size=20

# Aumentar o timeout
spring.datasource.hikari.connection-timeout=60000

# Ativar logs de vazamento
spring.datasource.hikari.leak-detection-threshold=60000

❌ Too Many Connections​

PostgreSQL: FATAL: too many connections for role "postgres"

Causa: Pool muito grande ou múltiplas instâncias

Solução:

# Reduzir o pool
spring.datasource.hikari.maximum-pool-size=5

# Verificar o max_connections do PostgreSQL
# SHOW max_connections;

❌ Connection Leak​

HikariPool-1 - Connection leak detection triggered

Causa: Conexão nunca retornada ao pool

Solução:

# Ativar detecção de vazamento
spring.datasource.hikari.leak-detection-threshold=30000

Depois, encontre e corrija o código problemático (conexão não fechada).


9. Resumo​

Pontos-Chave​

ConceitoDescrição
DatasourceFornece conexões para o banco de dados
HikariCPPool de conexões padrão (o mais rápido)
minimum-idleConexões mínimas mantidas
maximum-pool-sizeConexões máximas
connection-timeoutTempo máx para obter uma conexão

Checklist de Configuração​

✅ Definir spring.datasource.url
✅ Definir username/password
✅ Configurar minimum-idle e maximum-pool-size
✅ Ajustar os timeouts conforme o ambiente
✅ Monitorar com Actuator

Configuração Recomendada​

# Produção
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=myuser
spring.datasource.password=${DB_PASSWORD}

spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.pool-name=MyAppPool

🎯 Próximo Passo​

Agora que você entende como as conexões são gerenciadas, é hora de aprender como proteger a integridade dos seus dados com transações.

➡️ Capítulo 2: Gerenciamento de Transações (@Transactional)


⬅️ Voltar ao Módulo 7