CodeRigor

LESSON

Bind parameters and make writes atomic

Preserve the operation error, clean up failed transactions and keep names in parameter arguments.

Parameterized queries separate SQL structure from values. An owner named R&D O’Neil should be data, not a quoting problem. The lab also tests a name shaped like an injection attempt and expects no matching rows, without changing the SQL statement.

A transaction gives a related multi-write operation one commit boundary. The application inserts a note and its created event together. An induced event foreign-key failure must roll back the note too. Cleanup still matters when an operation errors, a commit fails or the caller is canceled.

Bind parameters and make writes atomic
start / 3
Preserve the operation error, clean up failed transactions and keep names in parameter arguments.
Bind parameters and make writes atomic
Preserve the operation error, clean up failed transactions and keep names in parameter arguments.

Run the operation, then commit only after it succeeds. On every other exit, attempt rollback with a short cleanup context. context.WithoutCancel keeps useful values without inheriting a canceled signal; the added two-second timeout prevents cleanup from waiting indefinitely.

Rollback is best effort. Preserve the original operation/commit failure rather than replacing it with a cleanup error. Deferred cleanup also runs during a panic, after which the panic continues. The real pgx transaction implements the small interface used in the hosted tests.

Go
package main
import ("fmt")
func main(){
query:="WHERE owner=$1";args:=[]any{"R&D O'Neil"};fmt.Println(query);fmt.Println(args[0])
}

The SQL string contains $1 and a separate argument slice contains the owner name. Never quote or escape an input manually to assemble this query. The maintained driver handles parameter transport; this course does not invent a PostgreSQL wire protocol.

The atomic-write probe compares actual note/event counts before and after a deliberately failed second write. It does not rely on sequence continuity, because sequence allocations may leave gaps after failure. The helper’s cleanup contract and actual database transaction are checked separately.

Review source, target and evidence
start / 3
A successful migration includes typed values, actual database behavior and explicit cleanup.
Review source, target and evidence
A successful migration includes typed values, actual database behavior and explicit cleanup.
Go
package main
import ("fmt";"context";"time")
func main(){
ctx,cancel:=context.WithCancel(context.Background());cancel();cleanup,stop:=context.WithTimeout(context.WithoutCancel(ctx),time.Second);defer stop();fmt.Println(ctx.Err()==context.Canceled,cleanup.Err()==nil)
}

Implement transaction ownership and verify success, failure, cancellation cleanup and panic behavior. Read the actual parameterized query before moving on to pool/query lifetimes.

Watch & read

Free lectures, talks and readings that cover this skill from another angle. All resources →

Optional database overview. The authored lessons and real local lab teach the exact schema, migration and application-lifetime boundaries used here.