How to Use the Redis WATCH Command

Have a Database Problem? Speak with an Expert for Free
Get Started >>

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

Keep in the know!

Subscribe to our emails and we’ll let you know what’s going on at ObjectRocket. We hate spam and make it easy to unsubscribe.