2.0 KiB
Transactions (MULTI
/EXEC
)
Start a transaction by calling .multi()
, then chaining your commands. When you're done, call .exec()
and you'll get an array back with your results:
const [setReply, getReply] = await client.multi()
.set('key', 'value')
.get('another-key')
.exec();
exec<'typed'>()
/execTyped()
A transaction invoked with .exec<'typed'>
/execTyped()
will return types appropriate to the commands in the transaction:
const multi = client.multi().ping();
await multi.exec(); // Array<ReplyUnion>
await multi.exec<'typed'>(); // [string]
await multi.execTyped(); // [string]
⚠️ this only works when all the commands are invoked in a single "call chain"
WATCH
You can also watch keys by calling .watch()
. Your transaction will abort if any of the watched keys change.
The WATCH
state is stored on the connection (by the server). In case you need to run multiple WATCH
& MULTI
in parallel you'll need to use a pool.
execAsPipeline
execAsPipeline
will execute the commands without "wrapping" it with MULTI
& EXEC
(and lose the transactional semantics).
await client.multi()
.get('a')
.get('b')
.execAsPipeline();
the diffrence between the above pipeline and Promise.all
:
await Promise.all([
client.get('a'),
client.get('b')
]);
is that if the socket disconnects during the pipeline, any unwritten commands will be discarded. i.e. if the socket disconnects after GET a
is written to the socket, but before GET b
is:
- using
Promise.all
- the client will try to executeGET b
when the socket reconnects - using
execAsPipeline
-GET b
promise will be rejected as well