TransactionResult
is the outcome of a MULTI/EXEC transaction run with
transaction-exec or the with-transaction
macro. The three variants are the three things Redis can do with a transaction,
and they need telling apart: Executed means it ran and carries one reply per
command, Aborted means a WATCHed key changed underneath it, and
QueueFailed means the server refused one or more commands before EXEC and
ran none of them.
A command that failed at runtime — WRONGTYPE, say — does not abort a
transaction: Redis runs the rest and reports the failure in place, so it arrives
as a RESP.Err element inside Executed.
(match (with-transaction &r
(incr @"counter")
(set @"key" @"val"))
(Result.Success (TransactionResult.Executed replies))
(println* "ran " (Array.length &replies) " commands")
(Result.Success (TransactionResult.Aborted))
(println* "a watched key changed; retry")
(Result.Success (TransactionResult.QueueFailed errs))
(println* "rejected before EXEC: " &(Array.length &errs))
(Result.Error e) (IO.errorln &e))
decode-replies
(Fn [(Ref (Array RESP) a), Int] (Result TransactionResult String))
(decode-replies replies n)
decodes the n + 2 replies to a transaction over n queued commands.
replies must hold MULTI’s reply, one queue acknowledgement per command and
EXEC’s reply, in that order — see
transaction-exec, which is what normally
produces them.
An EXEC array becomes Executed, carrying one reply per command; those
replies are passed through untouched, so a command that failed at runtime (e.g.
WRONGTYPE) stays a RESP.Err element, exactly as Redis reports it. A null
EXEC array becomes Aborted, meaning a WATCHed key changed. An EXEC error
becomes QueueFailed with the index and message of every command the server
refused to queue.
Returns an Error if n is negative, if MULTI itself failed, if EXEC
errored without any command having failed to queue, or if the reply stream does
not have the shape the protocol guarantees — a wrong number of replies, or an
EXEC array whose length does not match the number of queued commands.
delete
(Fn [TransactionResult] ())
deletes a TransactionResult. This should usually not be called manually.