Implement Go database access with context, pool tuning, transaction boundaries, and repository seams. Use when building repositories, tuning `sql.DB` or `pgx`, or reviewing DB transaction flow in Go.
Scanned 9/4/2026
Install to Claude Code
npx -y skills add gabrielmoreira/agent-skills-mirror --skill golang-database --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Golang Database?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/gabrielmoreira-golang-database)More formats (shields.io, HTML) on the badges page.
---
name: golang-database
description: Implement Go database access with context, pool tuning, transaction boundaries, and repository seams. Use when building repositories, tuning `sql.DB` or `pgx`, or reviewing DB transaction flow in Go.
metadata:
triggers:
files:
- 'internal/adapter/repository/**'
keywords:
- database
- sql
- postgres
- gorm
- sqlc
- pgx
---
# Golang Database
## **Priority: P0 (CRITICAL)**
## Rules
- Prefer explicit SQL or generated query layers when performance and shape matter.
- Configure the pool; defaults are rarely enough for real traffic.
- Pass `context.Context` as the first argument to every query path.
- **Strict Parameterization**: Always use parameterized placeholders (`?`, `$1`); never interpolate user strings into queries.
- **Dynamic IN Batching**: Generate safe placeholders (`strings.Repeat("?,", len(ids))`) or `sqlx.In` and partition lists into chunks ≤ 1,000 items to avoid driver parameter limits.
- **Explicit Column Aliasing**: Always alias duplicate column names in multi-table queries (e.g. `m.code AS code`); drivers map by name and silently collide on joins.
- **Transaction Boundaries**: Manage transactions at the service layer using `withTx(ctx, db, fn)` with mandatory `defer tx.Rollback()`. Keep transactions short and focused on writes.
- **Streaming & Keyset Pagination**: Stream large result sets using `rows.Next()` directly into models to prevent unbounded memory allocation.
## Recipe
1. **Choose the access layer**: `database/sql`, `pgx`, `sqlx`, `sqlc`, or ORM only if standardized.
2. **Tune the pool**: max open, max idle, connection lifetime, and idle lifetime.
3. **Hide storage details behind repository methods** or query services.
4. **Close rows and inspect `rows.Err()`**.
5. **Wrap multi-step writes in one transaction** using a `withTx` helper with `defer tx.Rollback()`.
6. **Chunk large slice lookups**: partition slices into batches of ≤ 1,000 before running `IN` queries.
## Verify
- [ ] Query methods accept `context.Context`.
- [ ] Pool settings are explicit.
- [ ] Rows are closed and iteration errors checked (`rows.Err()`).
- [ ] Large `IN (...)` queries chunk parameters into batches of ≤ 1,000.
- [ ] Joined queries use explicit column aliases without `SELECT *`.
- [ ] Transaction scope matches one business action and uses `defer tx.Rollback()`.
- [ ] Retry/idempotency policy is clear for contested writes.
## Anti-Patterns
- **No global db var**: inject DB connection via constructor.
- **No context-less queries**: use `QueryContext`/`ExecContext`; bare queries ignore timeouts.
- **No string concatenation in SQL**: never build dynamic clauses with `fmt.Sprintf` or `+`.
- **No unbounded IN lists**: avoid passing un-chunked slices with > 1,000 items into a single query.
- **No SELECT \* on Joins**: avoid unaliased duplicate column names across joined tables.
- **No leaked rows**: always `defer rows.Close()` and check `rows.Err()`.
- **No transaction split-brain**: handler, repo, and service cannot each open their own transaction for one unit of work.
## References
- [Framework Map](../references/framework-map.md)
- [Repository Pattern Implementation](references/repository-pattern.md)
- [Connection Tuning](references/connection-tuning.md)
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!