{
  "schema_version": 2,
  "id": "develop/clients/dotnet/transpipe",
  "title": "Pipelines and transactions",
  "url": "https://redis.io/docs/latest/develop/clients/dotnet/transpipe/",
  "summary": "Learn how to use Redis pipelines and transactions",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-09-08T15:21:05+01:00",
  "page_type": "content",
  "content_hash": "9fe9f01480151bbdfd518217eea0a7859f567232a65cf33fec2e97a1e0843eff",
  "sections": [
    {
      "id": "execute-a-pipeline",
      "title": "Execute a pipeline",
      "role": "content",
      "text": "`StackExchange.Redis` pipelines commands by using its asynchronous command\nmethods. Start the operations without waiting for each one immediately, then\nwait for their tasks after you have queued the commands. The multiplexer sends\nthe requests as soon as possible and processes the responses when they arrive.\nSee the StackExchange.Redis\n[Pipelines and Multiplexers](https://seredis.dev/PipelinesMultiplexers.html)\npage for more information.\n\nFoundational: Use pipelines to batch multiple commands together and reduce network round trips\n\n**Difficulty:** Beginner\n\n**Available in:** C#\n\n##### C#\n\n[code example]"
    },
    {
      "id": "execute-a-transaction",
      "title": "Execute a transaction",
      "role": "content",
      "text": "A transaction queues commands on an `ITransaction` object that you create with\n`CreateTransaction()`. Call async command methods on that object, then call\n`Execute()` or `ExecuteAsync()` to attempt the transaction. The queued command\ntasks complete after the transaction executes.\n\nFoundational: Use transactions to execute multiple commands atomically without interruption from other clients\n\n**Difficulty:** Beginner\n\n**Available in:** C#\n\n##### C#\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\nto different keys. The basic idea is to watch for changes to any\nkeys that you use in a transaction while you are processing the\nupdates. If the watched keys do change, you must restart the updates\nwith the latest data from the keys. See\n[Transactions](https://redis.io/docs/latest/develop/using-commands/transactions)\nfor more information about optimistic locking.\n\nThe approach to optimistic locking that other clients use\n(adding the [`WATCH`](https://redis.io/docs/latest/commands/watch) command\nexplicitly to a transaction) doesn't work well with the\n[multiplexing](https://redis.io/docs/latest/develop/clients/pools-and-muxing)\nsystem that `StackExchange.Redis` uses.\nInstead, `StackExchange.Redis` relies on conditional execution of commands\nto get a similar effect.\n\nUse the `AddCondition()` method to abort a transaction if a particular\ncondition doesn't hold throughout its execution. If the transaction\ndoes abort then the `Execute()` method returns a `false` value,\nbut otherwise returns `true`.\n\nFor example, the `KeyNotExists` condition aborts the transaction\nif a specified key exists or is added by another client while the\ntransaction executes:\n\nOptimistic locking: Use conditions to monitor keys for changes and abort transactions when conflicts occur\n\n**Difficulty:** Intermediate\n\n**Available in:** C#\n\n##### C#\n\n[code example]\n\n\n\nYou can also use a `When` condition on certain individual commands to\nspecify that they only execute when a certain condition holds\n(for example, the command does not change an existing key).\nSee\n[Conditional execution](https://redis.io/docs/latest/develop/clients/dotnet/condexec)\nfor a full description of transaction and command conditions."
    }
  ],
  "examples": [
    {
      "id": "execute-a-pipeline-ex0",
      "language": "csharp",
      "code": "var setTasks = new[]\n        {\n            db.StringSetAsync(\"seat:0\", \"#0\"),\n            db.StringSetAsync(\"seat:1\", \"#1\"),\n            db.StringSetAsync(\"seat:2\", \"#2\"),\n            db.StringSetAsync(\"seat:3\", \"#3\"),\n            db.StringSetAsync(\"seat:4\", \"#4\")\n        };\n        foreach (var setTask in setTasks)\n        {\n            db.Wait(setTask);\n        }\n\n        var resp1Task = db.StringGetAsync(\"seat:0\");\n        var resp2Task = db.StringGetAsync(\"seat:3\");\n        var resp3Task = db.StringGetAsync(\"seat:4\");\n\n        var resp1 = db.Wait(resp1Task);\n        Console.WriteLine(resp1); // >>> #0\n\n        var resp2 = db.Wait(resp2Task);\n        Console.WriteLine(resp2); // >>> #3\n\n        var resp3 = db.Wait(resp3Task);\n        Console.WriteLine(resp3); // >>> #4",
      "section_id": "execute-a-pipeline"
    },
    {
      "id": "execute-a-transaction-ex0",
      "language": "csharp",
      "code": "var trans = db.CreateTransaction();\n\n        var incr1 = trans.StringIncrementAsync(\"counter:1\", 1);\n        var incr2 = trans.StringIncrementAsync(\"counter:2\", 2);\n        var incr3 = trans.StringIncrementAsync(\"counter:3\", 3);\n\n        bool committed = db.Wait(trans.ExecuteAsync());\n\n        var resp4 = db.Wait(incr1);\n        Console.WriteLine(resp4); // >>> 1\n\n        var resp5 = db.Wait(incr2);\n        Console.WriteLine(resp5); // >>> 2\n\n        var resp6 = db.Wait(incr3);\n        Console.WriteLine(resp6);  // >>> 3",
      "section_id": "execute-a-transaction"
    },
    {
      "id": "watch-keys-for-changes-ex0",
      "language": "csharp",
      "code": "var watchedTrans = db.CreateTransaction();\n\n        watchedTrans.AddCondition(Condition.KeyNotExists(\"customer:39182\"));\n\n        var hashSetTask = watchedTrans.HashSetAsync(\n            \"customer:39182\",\n            [\n                new(\"name\", \"David\"),\n                new(\"age\", \"27\")\n            ]\n        );\n\n        bool succeeded = db.Wait(watchedTrans.ExecuteAsync());\n        db.Wait(hashSetTask);\n        Console.WriteLine(succeeded); // >>> true",
      "section_id": "watch-keys-for-changes"
    }
  ]
}
