# Chains

Chains ensure jobs run sequentially for the same entity. Use when order matters (e.g., webhook processing, account balance updates).

```elixir
defmodule MyApp.WebhookWorker do
  use Oban.Pro.Worker,
    queue: :webhooks,
    chain: [by: [args: :account_id]]

  @impl Oban.Pro.Worker
  def process(%Oban.Job{args: args}) do
    MyApp.Account.handle_webhook(args["account_id"], args["event"])
  end
end
```

## Partitioning

```elixir
chain: [by: :worker]                        # All jobs of this worker chain together
chain: [by: [args: :account_id]]            # Chain by account_id across workers
chain: [by: [:worker, args: :account_id]]   # Chain by worker AND account_id
chain: [by: [args: [:account_id, :region]]] # Chain by multiple args
```

## Handling failures

```elixir
chain: [by: [args: :id], on_discarded: :hold, on_cancelled: :hold]
```

- `:ignore` (default) — continue processing downstream jobs
- `:hold` — stop the chain until the failed job is resolved
