Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O pooling de conexões melhora o desempenho das aplicações ao reutilizar conexões de banco de dados em vez de criar novas para cada solicitação. Abrir uma conexão envolve múltiplas etapas demoradas:
- O driver estabelece um socket de rede.
- O driver completa o handshake TLS.
- O driver autentica com o servidor.
- O driver valida os parâmetros da conexão.
O pool de conexão mantém as conexões abertas e disponíveis para reutilização, então seu app não precisa repetir esses passos para cada solicitação.
Comportamento padrão
O pool de conexões está ativado por padrão quando você cria sua primeira conexão. As configurações padrão são:
| Setting | Valor padrão | Descrição |
|---|---|---|
max_size |
100 | Número máximo de conexões para cada cadeia de conexão distinta. |
idle_timeout |
600 segundos (10 minutos) | Número de segundos antes do encerramento das conexões ociosas. |
import mssql_python
# Pooling is automatically enabled with defaults
conn = mssql_python.connect(connection_string)
Configurar o pool de conexões
Configure o pooling antes de criar qualquer conexão:
import mssql_python
# Configure custom pool settings
mssql_python.pooling(max_size=50, idle_timeout=300)
# Now create connections
conn = mssql_python.connect(connection_string)
Parameters
A pooling() função aceita os seguintes parâmetros:
| Parâmetro | Tipo | Default | Descrição |
|---|---|---|---|
max_size |
int | 100 | Número máximo de conexões no pool por cadeia de conexão. |
idle_timeout |
int | 600 | Segundos antes das conexões ociosas serem despejadas da piscina. |
enabled |
bool | Verdade | Ative ou desative o agrupamento. |
Desativar o pooling de conexões
Para desativar o pooling, chame pooling() com enabled=False antes de criar conexões:
import mssql_python
mssql_python.pooling(enabled=False)
# Connections are now created and destroyed per use
conn = mssql_python.connect(connection_string)
Note
Defina a configuração do pooling antes de estabelecer qualquer conexão. Ligar pooling() após criar conexões não tem efeito.
Como funciona o agrupamento
Isolamento da corda de conexão
Cada cadeia de conexão única mantém seu próprio pool de conexões independente. Pools não compartilham conexões entre diferentes strings de conexão:
# These use separate pools
conn1 = mssql_python.connect("Server=<server1>;Database=<database1>;...")
conn2 = mssql_python.connect("Server=<server2>;Database=<database2>;...")
Ciclo de vida da conexão
Obter (estabelecendo uma conexão):
- A piscina remove conexões obsoletas (paradas e expiradas).
- O pool tenta reutilizar uma conexão existente:
- Ele verifica se a conexão está ativa.
- Ele reinicia o estado da conexão.
- Se ambos os testes tiverem sucesso, a conexão retorna.
- Se não houver conexão reutilizável e o pool estiver abaixo de
max_size, o driver cria uma nova conexão. - Se o pool atingir a capacidade máxima e não houver conexões válidas, o driver gera um erro.
Liberação (retornando uma conexão):
- Se a piscina tiver capacidade, ela armazena a conexão para reutilização.
- Se o pool estiver em
max_size, o driver fecha a conexão imediatamente.
Verificações de saúde da conexão
O driver realiza verificações de integridade da conexão antes de reutilizar uma conexão do pool.
- Verificação de disponibilidade: Garante que a conexão de rede continua válida.
- Verificação de reset: Reinicia o estado da sessão (nível de isolamento, configurações) para reutilização limpa.
Se qualquer uma das verificações falhar, o pool descarta a conexão e cria uma nova.
Limpeza automática
-
Tempo limite de inatividade: O driver fecha conexões que permanecem sem uso por mais tempo que o valor de
idle_timeout. -
Encerramento do processo: Um
atexitmanipulador fecha todas as conexões agrupadas quando o processo Python é encerrado.
Práticas recomendadas
Dimensione sua piscina de forma adequada
Ajuste o tamanho do pool de acordo com a concorrência da sua aplicação.
# For a web application with 20 concurrent requests
mssql_python.pooling(max_size=25) # Slightly more than expected concurrency
Uso de gerentes de contexto
Os gerentes de contexto garantem que você retorne corretamente as conexões ao pool.
with mssql_python.connect(connection_string) as conn:
cursor = conn.cursor()
cursor.execute("SELECT TOP 5 Name, ListPrice FROM Production.Product")
rows = cursor.fetchall()
# Connection returned to pool
Mantenha as cordas de conexão consistentes
Parâmetros diferentes nas strings de conexão criam pools separados.
# These create THREE separate pools (inefficient)
conn1 = mssql_python.connect("Server=<server>;Database=<database>;Encrypt=yes;")
conn2 = mssql_python.connect("SERVER=<server>;DATABASE=<database>;ENCRYPT=yes;") # Different case
conn3 = mssql_python.connect("Server=<server>;Database=<database>;Encrypt=yes;", timeout=30) # Extra parameter
# Use a constant connection string instead
CONNECTION_STRING = "Server=<server>;Database=<database>;Encrypt=yes;"
conn1 = mssql_python.connect(CONNECTION_STRING)
conn2 = mssql_python.connect(CONNECTION_STRING) # Same pool
Considere os limites de conexão do SQL do Azure
Banco de Dados SQL do Azure aplica limites de conexão com base no nível de serviço. Os valores a seguir são aproximados; Confira a documentação vinculada para os limites atuais:
| Nível de serviço | Máximo de conexões simultâneas |
|---|---|
| Básico | 30 |
| Padrão S0-S2 | 60-120 |
| Versão padrão S3 e posteriores | 200 |
| Premium | 500 |
Reduza seu max_size valor abaixo desses limites.
# For Azure SQL Standard S2 (120 limit)
mssql_python.pooling(max_size=100) # Leave headroom
Ajuste o tempo limite de inatividade para sua carga de trabalho
-
Contatos frequentes: Use um valor mais longo
idle_timeoutpara manter as conexões quentes. -
Conexões esporádicas: Use um valor mais
idle_timeoutcurto para liberar recursos.
# High-frequency API: keep connections warm
mssql_python.pooling(idle_timeout=1800) # 30 minutes
# Batch job running every hour: release between runs
mssql_python.pooling(idle_timeout=60) # 1 minute
Limitations
A implementação atual apresenta algumas limitações em comparação com outros drivers:
| Característica | Status |
|---|---|
ClearPool() / ClearAllPools() |
Não disponível. |
| Estatísticas/monitoramento do pool | Não disponível. |
| Override por pool de conexão | Não disponível. |
| Tamanho mínimo da piscina | Não configurável. |
Exemplo: padrão de aplicação web
O exemplo a seguir do Flask mostra como as conexões são agrupadas de forma transparente entre as requisições:
import mssql_python
from flask import Flask, g
app = Flask(__name__)
# Configure pooling at startup
mssql_python.pooling(max_size=20, idle_timeout=300)
def get_db():
if 'db' not in g:
g.db = mssql_python.connect(app.config['DATABASE_URL'])
return g.db
@app.teardown_appcontext
def close_db(error):
db = g.pop('db', None)
if db is not None:
db.close() # Returns to pool
@app.route('/products')
def list_products():
conn = get_db()
cursor = conn.cursor()
cursor.execute("SELECT TOP 5 Name, ListPrice FROM Production.Product")
return cursor.fetchall()
Reconhecer o cansaço na piscina
Quando todas as conexões da piscina estão em uso e você solicita uma nova conexão, você vê sintomas como:
- As conexões ficam travadas ou expiram enquanto aguardam uma conexão disponível.
- A taxa de processamento da aplicação cai repentinamente quando submetida a carga.
- O uso de memória aumenta à medida que o driver cria conexões que não pode reutilizar.
Causas comuns:
- As conexões não são retornadas ao pool. Sempre feche as conexões quando terminar, ou use gerenciadores de contexto. Uma conexão que não está fechada permanece desligada.
- Pool muito pequeno para a carga de trabalho. Se você tiver 50 solicitações simultâneas, mas
max_size=20, 30 solicitações ficam esperando. - Consultas de longa duração mantêm conexões. Divida operações longas ou use conexões dedicadas para processamento em lote.
Como corrigir:
# 1. Always use context managers to guarantee return
with mssql_python.connect(connection_string) as conn:
cursor = conn.cursor()
cursor.execute("SELECT ...")
rows = cursor.fetchall()
# Connection returned to pool here, even if an exception occurs
# 2. Size the pool to match your concurrency
mssql_python.pooling(max_size=50) # Match or slightly exceed expected concurrent connections
# 3. Reduce idle timeout if connections go stale
mssql_python.pooling(idle_timeout=120)