How to Use the Redis WATCH Command
Introduction
If you’re using Redis to manage your data, it’s important to understand how to use transactions with this key-value data store. Transactions in Redis bear little resemblance to transactions in a typical relational database management system (RDBMS). Fortunately, Redis has several useful commands to help you manage transactions effectively. In this article, we’ll discuss the Redis WATCH command and explain how to use it.
Prerequisites
In order to follow along with the examples in this tutorial, you’ll need to ensure that Redis is properly configured on your system. It’s also helpful to have a basic understanding of Redis before learning more about the Redis WATCH command.
What are Redis Transactions?
A handful of commands– WATCH
, EXEC
, DISCARD
and MULTI
— form the building blocks of Redis transactions. These building blocks allow a set of commands to be executed in just one step, and they come with two key guarantees: First, they ensure that the commands in the transaction will be executed in a sequential manner and are serialized. This means that a request from a different client won’t be served while a Redis transaction is being executed. In addition, a Redis transaction is guaranteed to be “atomic”, which means that either all of the commands in it are executed, or none of them are executed.
REDIS Transaction Usage
Now that we’ve talked about what a Redis transaction is, we can move forward and look at how it’s used.
A Redis transaction is initiated with the use of the MULTI
command, which always returns “OK” as a reply. At this stage, a user is able to execute numerous commands. Redis queues these commands and only executes them when the EXEC
command is invoked. If the DISCARD
command is invoked, the queue is flushed and Redis will exit the transaction.
What is the Redis WATCH Command?
In the previous section, we provided a high-level introduction to Redis transactions and how they’re used. Now, we’ll focus our discussion on the Redis WATCH command and the role it plays within a Redis transaction.
The WATCH
command works by making the EXEC
command conditional; in other words, Redis will only perform a transaction if the WATCHed keys were not modified. If a WATCHed key was indeed modified, the transaction won’t be entered at all.
The WATCH
command can be called numerous times, and one WATCH
call can involve any number of keys. Watch calls simply monitor for changes starting from the point where WATCH
was called until EXEC
is called. Once EXEC
is invoked, all the keys will be UNWATCHed, whether or not the transaction in question was aborted. Closing a client connection also triggers all keys to be UNWATCHed.
Using REDIS Watch Command for Optimistic Locking
The Redis WATCH
command provides check-and-set (CAS) functionality to Redis transactions. Keys that are WATCHed are continuously monitored for changes; if even one WATCHed key is changed before the EXEC
command is called, the entire transaction will be canceled and EXEC
will return NULL
to indicate that the transaction was unsuccessful.
Let’s consider an example where we need to increase a key’s value by 1. We can use the following command:
1 2 3 | num = GET sampleKey num = num + 1 SET sampleKey $num |
The commands shown above will work without any issues as long as there is only a single user performing the operation at a particular time. Things become challenging if multiple users attempt to increase the key’s value at the same time, resulting in a race condition. Imagine that the value of original value of sampleKey
is 13, and two clients attempt to increment the value at the same time. Both will increase the value to 14 and SET
that quantity as the key’s value. This will result in the final value being 14 instead of 15.
We can eliminate this potential problem by using the WATCH
command:
1 2 3 4 5 6 | WATCH sampleKey num = GET sampleKey num = num + 1 MULTI SET sampleKey $num EXEC |
With this code, if a race condition occurs and a client modifies the value of num
at some point between our invoking WATCH
and our invoking EXEC
, the transaction will abort. We would need to repeat the transaction when the race condition is no longer present.
This locking process is also known as “optimistic locking”, and it provides an effective way to safeguard against race conditions. Most of the time, there are multiple clients accessing various keys, so the chances of these “collisions” are quite small, and it’s not likely that a transaction will need to be repeated.
Conclusion
Transactions are a fundamental component of Redis, so it’s important to know how to use them effectively. The EXEC
, WATCH
, MULTI
and DISCARD
commands act as the foundation of Redis transactions, allowing you to manage the execution of transactions and maintain data integrity. In this article, we focused on the Redis WATCH
command and talked about how the command is used. With the explanations provided in this article, you’ll be well-equipped to use Redis transaction commands in your own applications.
Pilot the ObjectRocket Platform Free!
Try Fully-Managed CockroachDB, Elasticsearch, MongoDB, PostgreSQL (Beta) or Redis.
Get Started