@@ -134,8 +134,12 @@ Important caveats when using ``EVALSHA`` in a cluster pipeline:
134134 fails with ``NOSCRIPT `` (``redis.exceptions.NoScriptError ``).
135135- Unlike the non-pipelined ``Script `` object, **a cluster pipeline performs no
136136 automatic reload or retry ** on ``NOSCRIPT ``. Recovery is the caller's
137- responsibility: catch ``NoScriptError ``, re-run ``SCRIPT LOAD ``, and
138- re-execute the pipeline. Because zero-key ``EVALSHA `` is routed to a random
137+ responsibility: catch ``NoScriptError ``, re-run ``SCRIPT LOAD ``, then retry
138+ only when replay is safe (for example an idempotent or single-command
139+ pipeline). Blindly re-executing a multi-command pipeline can duplicate
140+ side effects: Redis still runs the rest of a non-transactional batch when
141+ one ``EVALSHA `` returns ``NOSCRIPT ``, and the client raises only after
142+ reading every response. Because zero-key ``EVALSHA `` is routed to a random
139143 primary, the script must be present on **all ** primaries.
140144- In a **transactional ** pipeline, a ``NOSCRIPT `` from ``EVALSHA `` is raised at
141145 ``EXEC `` time and does **not ** roll back the other commands (this follows
@@ -149,9 +153,9 @@ Important caveats when using ``EVALSHA`` in a cluster pipeline:
149153 ... with rc.pipeline() as pipe:
150154 ... pipe.evalsha(sha, 1 , " {user} :1" )
151155 ... return pipe.execute()
152- >> > try :
153- ... result = run()
154- ... except NoScriptError:
155- ... # a node was missing the script (e.g. after failover/upgrade)
156- ... sha = rc.script_load(lua) # reload on current primaries
157- ... result = run()
156+ >>> try :
157+ ... result = run()
158+ ... except NoScriptError:
159+ ... # single-command pipeline: safe to reload and retry
160+ ... sha = rc.script_load(lua) # reload on current primaries
161+ ... result = run()
0 commit comments