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á:
- ✅ O que é um Datasource e por que ele é importante
- ✅ Como o Spring Boot configura automaticamente as conexões
- ✅ Configurar o HikariCP (o pool padrão)
- ✅ Otimizar os parâmetros para produção
- ✅ 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
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
| Conceito | Descrição |
|---|---|
| Datasource | Fornece conexões para o banco de dados |
| HikariCP | Pool de conexões padrão (o mais rápido) |
| minimum-idle | Conexões mínimas mantidas |
| maximum-pool-size | Conexões máximas |
| connection-timeout | Tempo 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)