{
  "filename": "orders/reserve.go",
  "rule": "- name: reservation-tx-handle\n  where: \"orders/reserve.go\"\n  ensure: >-\n    The inventory UPDATE and order INSERT must both use tx.ExecContext inside the same transaction, never db.ExecContext for the order write.",
  "corrected": "package orders\nimport (\n    \"context\"\n    \"database/sql\"\n    \"errors\"\n)\n\nfunc Reserve(ctx context.Context, db *sql.DB, tenant, sku string, qty int) error {\n    if qty <= 0 { return errors.New(\"invalid quantity\") }\n    tx, err := db.BeginTx(ctx, nil)\n    if err != nil { return err }\n    defer tx.Rollback()\n    stock, err := tx.ExecContext(ctx, \"UPDATE inventory SET available=available-$1 WHERE tenant_id=$2 AND sku=$3 AND available >= $1\", qty, tenant, sku)\n    if err != nil { return err }\n    count, err := stock.RowsAffected()\n    if err != nil { return err }\n    if count != 1 { return errors.New(\"insufficient stock\") }\n    _, err = tx.ExecContext(ctx, \"INSERT INTO orders (tenant_id,sku,quantity) VALUES ($1,$2,$3)\", tenant, sku, qty)\n    if err != nil { return err }\n    return tx.Commit()\n}\n",
  "broken": "package orders\nimport (\n    \"context\"\n    \"database/sql\"\n    \"errors\"\n)\n\nfunc Reserve(ctx context.Context, db *sql.DB, tenant, sku string, qty int) error {\n    if qty <= 0 { return errors.New(\"invalid quantity\") }\n    tx, err := db.BeginTx(ctx, nil)\n    if err != nil { return err }\n    defer tx.Rollback()\n    stock, err := tx.ExecContext(ctx, \"UPDATE inventory SET available=available-$1 WHERE tenant_id=$2 AND sku=$3 AND available >= $1\", qty, tenant, sku)\n    if err != nil { return err }\n    count, err := stock.RowsAffected()\n    if err != nil { return err }\n    if count != 1 { return errors.New(\"insufficient stock\") }\n    _, err = db.ExecContext(ctx, \"INSERT INTO orders (tenant_id,sku,quantity) VALUES ($1,$2,$3)\", tenant, sku, qty)\n    if err != nil { return err }\n    return tx.Commit()\n}\n",
  "regression": [
    "_, err = tx.ExecContext(ctx, \"INSERT",
    "_, err = db.ExecContext(ctx, \"INSERT"
  ],
  "test_scenarios": [
    [
      "Both writes succeed",
      "Commit once"
    ],
    [
      "INSERT fails",
      "Stock UPDATE rolls back"
    ],
    [
      "Request context canceled",
      "Database operations observe cancellation"
    ],
    [
      "Insufficient stock",
      "No INSERT"
    ]
  ],
  "test_source": null,
  "test_command": "go test ./orders -run TestReserve"
}