{
  "id": "transpipe",
  "title": "Pipelines and transactions",
  "url": "https://redis.io/docs/latest/develop/clients/ruby/transpipe/",
  "summary": "Learn how to use Redis pipelines and transactions",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-07-31T16:56:30+01:00",
  "page_type": "content",
  "content_hash": "69b385c19b7ac48c4541f74a4c680432ca78b35313ea6f3c7571835fe8222faf",
  "sections": [
    {
      "id": "execute-a-pipeline",
      "title": "Execute a pipeline",
      "role": "content",
      "text": "To execute commands in a pipeline with `redis-rb`, call `pipelined()` and queue\ncommands in the block. Redis executes them as a batch and `pipelined()` returns\nthe results in order:\n\nFoundational: Use pipelined to batch multiple commands together and reduce network round trips\n\n**Difficulty:** Beginner\n\n**Available in:** Ruby\n\n##### Ruby\n\n[code example]"
    },
    {
      "id": "execute-a-transaction",
      "title": "Execute a transaction",
      "role": "content",
      "text": "Transactions use `multi()`. Commands queued inside the block run atomically\nwhen the block finishes, and `multi()` returns the results in order:\n\nFoundational: Use multi to execute multiple commands atomically without interruption from other clients\n\n**Difficulty:** Beginner\n\n**Available in:** Ruby\n\n##### Ruby\n\n[code example]"
    },
    {
      "id": "watch-keys-for-changes",
      "title": "Watch keys for changes",
      "role": "content",
      "text": "Redis supports *optimistic locking* to avoid inconsistent updates to keys that\nseveral clients may modify at the same time. The basic idea is to watch for\nchanges to any keys that you use in a transaction while you are preparing the\nupdate. If the watched keys do change, the transaction returns `nil` and you\nmust retry using the latest value from Redis. See\n[Transactions](https://redis.io/docs/latest/develop/using-commands/transactions)\nfor more information about optimistic locking.\n\nThe example below watches a key, reads its current value, and then updates it\ninside `multi()`:\n\nOptimistic locking: Use watch with multi and retry when another client modifies the watched key\n\n**Difficulty:** Intermediate\n\n**Available in:** Ruby\n\n##### Ruby\n\n[code example]"
    }
  ],
  "examples": [
    {
      "id": "execute-a-pipeline-ex0",
      "language": "ruby",
      "code": "r.pipelined do |pipe|\n  (0..4).each { |i| pipe.set(\"seat:#{i}\", \"##{i}\") }\nend\n\nseats = r.pipelined do |pipe|\n  pipe.get('seat:0')\n  pipe.get('seat:3')\n  pipe.get('seat:4')\nend\n\nputs seats[0] # >>> #0\nputs seats[1] # >>> #3\nputs seats[2] # >>> #4",
      "section_id": "execute-a-pipeline"
    },
    {
      "id": "execute-a-transaction-ex0",
      "language": "ruby",
      "code": "trans_results = r.multi do |tx|\n  tx.incrby('counter:1', 1)\n  tx.incrby('counter:2', 2)\n  tx.incrby('counter:3', 3)\nend\n\nputs trans_results[0] # >>> 1\nputs trans_results[1] # >>> 2\nputs trans_results[2] # >>> 3",
      "section_id": "execute-a-transaction"
    },
    {
      "id": "watch-keys-for-changes-ex0",
      "language": "ruby",
      "code": "r.set('shellpath', '/usr/syscmds/')\n\n# Watch the key, read its current value, then queue the update in a\n# transaction. `multi` returns `nil` if the watched key changed before\n# `EXEC` ran, in which case you would retry with the latest value.\nresult = r.watch('shellpath') do |client|\n  current_path = client.get('shellpath')\n  new_path = current_path + ':/usr/mycmds/'\n\n  client.multi do |tx|\n    tx.set('shellpath', new_path)\n  end\nend\n\nif result.nil?\n  puts 'Transaction aborted; retry with the latest value'\nelse\n  puts r.get('shellpath')\n  # >>> /usr/syscmds/:/usr/mycmds/\nend",
      "section_id": "watch-keys-for-changes"
    }
  ]
}
