11.2.1 Why locks in Lua?
Let’s first deal with the question of why we would decide to build a lock with Lua. There are two major reasons.
Technically speaking, when executing a Lua script with EVAL or EVALSHA, the first group of arguments after the script or hash is the keys that will be read or written within Lua (I mentioned this in two notes in sections 11.1.1 and 11.1.2). This is primarily to allow for later Redis cluster servers to reject scripts that read or write keys that aren’t available on a particular shard. If we don’t know what keys will be read/written in advance, we shouldn’t be using Lua (we should instead use WATCH/MULTI/EXEC or locks). As such, any time we’re reading or writing keys that weren’t provided as part of the KEYS argument to the script, we risk potential incompatibility or breakage if we transition to a Redis cluster later.
The second reason is because there are situations where manipulating data in Redis requires data that’s not available at the time of the initial call. One example would be fetching some HASH values from Redis, and then using those values to access information from a relational database, which then results in a write back to Redis. We saw this first when we were scheduling the caching of rows in Redis back in section 2.4. We didn’t bother locking in that situation because writing two copies of the same row twice wouldn’t have been a serious issue. But in other caching scenarios, reading the data to be cached multiple times can be more overhead than is acceptable, or could even cause newer data to be overwritten by older data.
Given these two reasons, let’s rewrite our lock to use Lua.