Identificação
Resumo
A aula 5 ataca um dos problemas mais clássicos — e mais subestimados — do desenvolvimento backend: concorrência. Começamos pelo cenário concreto da venda dupla do último ingresso (condição de corrida), passamos pelos pilares ACID, comparamos os 4 níveis de isolamento, escrevemos transações reais com BEGIN / COMMIT / ROLLBACK em TRY/CATCH, discutimos locks pessimistas vs otimistas e fechamos com triggers — gatilhos automáticos no banco — incluindo as armadilhas que fazem times maduros desconfiarem deles.
O fechamento é uma atividade prática em sala (90 min, em grupo, sem nota ponderada): cada equipe implementa uma stored procedure de compra de ingresso atômica, um trigger de auditoria em avaliacao e testa manualmente uma race condition com 2 sessões SQL simultâneas.
Objetivos de aprendizagem
- OA-1Identificar condições de corrida em código que parece correto mas falha sob concorrência.
- OA-2Explicar os 4 pilares ACID com exemplo de violação para cada.
- OA-3Escolher o nível de isolamento adequado para cada caso de uso, ciente das anomalias permitidas.
- OA-4Escrever transações com
BEGIN / COMMIT / ROLLBACKemTRY/CATCHque tratam falha corretamente. - OA-5Distinguir locks pessimistas (
SELECT FOR UPDATE) de otimistas (versionamento) e quando usar cada um. - OA-6Implementar trigger de auditoria correto, ciente do impacto em performance e debugging.
Pré-requisitos
- Aulas 3 e 4 concluídas: schema relacional do projeto modelado e populado com dados de teste.
- Acesso individual ao banco do projeto (SQL Server / PostgreSQL conforme stack do grupo).
- Cliente SQL configurado (DBeaver, Azure Data Studio, pgAdmin ou equivalente) capaz de abrir 2 sessões simultâneas.
Cronograma do dia
📚 Bloco 1 · Autoestudo
10h00 — 12h00Estudo individual orientado pelo material da aula 5.
- Leitura completa do Material da Aula 5 (ACID, isolamento, triggers).
- Capítulo 7 de Designing Data-Intensive Applications (Kleppmann) — Transactions.
- Pesquisa: 1 caso público de bug por race condition (ex.: overdraw bancário, double-spending).
- Caderno de bordo: anotar 1 dúvida concreta sobre níveis de isolamento.
📚 Leituras sugeridas:
- SET TRANSACTION ISOLATION LEVEL — Microsoft Docs (SQL Server).
- Concurrency Control — PostgreSQL Docs.
- How to Trace Locking — Brent Ozar.
- Designing Data-Intensive Applications, cap. 7 — Martin Kleppmann.
🎓 Bloco 2 · Instrução PE — Aula em metodologia ativa
14h00 — 16h00Encontro síncrono com o professor especialista.
- 14h00 — 14h15 · Daily.
- 14h15 — 14h55 · Teoria + live coding (race condition, ACID, isolamento, BEGIN/COMMIT/ROLLBACK, locks, triggers).
- 14h55 — 16h00 · Atividade prática em sala (1h05).
🍴 Intervalo · Almoço
12h00 — 14h00Janela livre.
🛠️ Bloco 3 · Desenvolvimento do projeto
16h00 — 18h00Janela de trabalho da equipe — continuidade da atividade prática.
- Finalizar
sp_comprar_ingressocom tratamento robusto e nível de isolamento explícito. - Finalizar
trg_avaliacao_auditcom captura de valores antigo/novo via tabelasinserted/deleted. - Documentar resultado dos testes de race condition (com lock vs sem lock) no
READMEda pastadb/. - Abrir Merge Request
feat(db): transactions + triggers de auditoriano repositório do grupo.
Detalhamento da instrução PE (14h00 — 16h00)
14h15
DailyDaily de abertura
Cada aluno apresenta em 1 minuto: 1 caso de race condition que pesquisei / 1 dúvida sobre isolamento / como meu projeto trata concorrência hoje.
14h25
TalkA condição de corrida em vídeo
Cenário do último ingresso: 2 usuários compram simultaneamente, sistema vende 2 com 1 em estoque. Por quê? Timeline visual T1 × T2 entre SELECT e UPDATE.
14h35
TalkACID + 4 níveis de isolamento
Os 4 pilares com exemplo de violação para cada. Tabela comparando READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE com as 4 anomalias clássicas.
14h45
CodingLive coding · BEGIN / COMMIT / ROLLBACK
Construção em sala da transação canônica de compra de ingresso com TRY/CATCH, checagem de @@ROWCOUNT e THROW manual quando estoque é zero.
14h55
TalkLocks + Triggers
Pessimista (SELECT FOR UPDATE) vs otimista (versionamento). Anatomia de um trigger: gatilho, tipos, tabelas mágicas inserted/deleted. Armadilhas: cascata, performance, debugging.
16h00
AtivaAtividade prática em sala — 1h05
Em grupo, no repositório do projeto: implementar sp_comprar_ingresso + trg_avaliacao_audit + teste de race condition com 2 sessões. Continuação na janela de dev (16h00 — 18h00).
Estratégias de metodologia ativa
- Race condition vivida, não narrada — antes de teoria, os alunos veem (ou abrem 2 sessões e tentam) o bug.
- Atividade em grupo no repositório real do projeto — sem nota ponderada, mas com Merge Request real avaliado pelo professor.
- Trigger ensinado com seus inimigos — boas práticas + armadilhas no mesmo slide para evitar uso ingênuo.
Em sistemas reais, "deu certo nos meus testes locais" não é prova: é hipótese. Concorrência só aparece quando duas coisas acontecem ao mesmo tempo.
Recursos e ferramentas
| Categoria | Recurso | Uso |
|---|---|---|
| Slides | slides/slide-lesson-5.html | Exposição na instrução PE |
| Material | materials/lesson-5-material.html | Autoestudo |
| Banco | SQL Server / PostgreSQL (conforme stack do grupo) | Atividade prática |
| Cliente SQL | DBeaver, Azure Data Studio ou pgAdmin | Abrir 2 sessões simultâneas para teste de race condition |
| Repositório | pasta db/ do projeto + README.md | Entrega da atividade via Merge Request |
Verificação de aprendizagem (atividade prática em sala — sem ponderada)
- CR-1
sp_comprar_ingresso(@userId, @espId)implementada comBEGIN / COMMIT / ROLLBACKdentro deTRY/CATCHe rejeição quando estoque é zero. - CR-2Lock pessimista aplicado no decremento de estoque (
SELECT ... FOR UPDATEou hint equivalente). - CR-3
trg_avaliacao_auditemAFTER INSERT/UPDATE/DELETEcapturando valores antigo e novo viainserted/deleted. - CR-4Teste manual de race condition documentado no
README: 2 sessões SQL competindo pelo último ingresso, comparando comportamento com lock vs sem lock. - CR-5Merge Request
feat(db): transactions + triggers de auditoriaaberto no repositório do grupo.
Nível de isolamento explícito (SET TRANSACTION ISOLATION LEVEL SERIALIZABLE) na sp_comprar_ingresso + análise no README sobre o impacto no throughput do sistema.
Esta aula não tem ponderada. A entrega é em grupo, via Merge Request, e serve como base para a aula 6 — onde o frontend mobile vai consumir essas procedures e triggers.
Conexão com a aula 6
A aula 6 sobe para o frontend mobile com React Native + MVVM — o consumidor das procedures e triggers que você acabou de blindar. O contrato definido aqui (entrada, saída, erros previstos da sp_comprar_ingresso) vira o contrato da camada de dados do mobile.
- A
sp_comprar_ingressode hoje vira a chamada da ViewModel de checkout. - O log de auditoria do trigger alimenta a tela de histórico do usuário.
- O tratamento de erro no
CATCHSQL define os estados visuais do mobile (sucesso, sem estoque, erro genérico).
Antes das 10h: ler material da aula 6, instalar Expo CLI, rodar projeto React Native em branco no celular pessoal e revisar o padrão MVVM (Model — View — ViewModel).