Redis's handling of transactions is so simple that Redis can only guarantee that commands in one client-initiated transaction can be executed consecutively, without inserting another client's commands, and when a client issues a multi command in a connection, This connection goes into a transaction context, and the subsequent command of the connection is not executed immediately, but is placed first in a queue, and Redis executes all the commands in the queue sequentially when the EXEC command is executed.
Multi marks the beginning of a transaction block.
Set name ZHANGDH
Set Age 30
EXEC commit
Multi
INCR Age
INCR Name
Exec first executes successfully and the second one will be an error.
This is where the Redis transaction needs to be improved.
Discard rollback, cancels the transaction, discards all commands inside the transaction block. Clears the command queue for the transaction and exits the transaction context.
In a redis transaction, the Watch command can be used to provide CAS (check-and-set) functionality. Suppose we monitor multiple keys before a transaction executes through the Watch command, and if any key value changes after watch, the EXEC command executes the transaction is discarded, and a null Multi-bulk answer is returned to inform the caller that the transaction execution failed. For example, once again, we assume that Redis does not provide the INCR command to achieve the atomic increment of the key values, and we can only write the corresponding code ourselves if we want to implement this function. The pseudo code is as follows:
val = GET MyKey
val = val + 1
SET MyKey $val
The above code is guaranteed to be correct only in the case of a single connection, because if more than one client is executing the code at the same time, there is a common error scenario in a multithreaded program-race contention (race condition). For example, both client A and B read the original value of the MyKey at the same time, assuming that the value is 10, and then two clients then add the value one after another set back to the Redis server, which results in a mykey result of 11 instead of 12 as we think. To solve a similar problem, we need the help of the Watch command, as shown in the following code:
WATCH MyKey
val = GET MyKey
val = val + 1
MULTI
SET MyKey $val
Exec
Unlike the previous code, the new code monitors the key with the watch command before it gets the value of MyKey, and then encloses the set command in the transaction, which effectively guarantees that each connection is executed before exec, if the value of the MyKey that is obtained by the current connection is modified by the other connected clients. The EXEC command that is currently connected will fail to execute. This allows the caller to know if the Val has been reset successfully after judging the return value.
Watch name
Set name ZJZ
Multi
Set name Zby
EXEC this transaction will fail. Output Name value is ZJZ
Redis Transaction Processing