A Redis transaction is based on four commands:
Create transaction
The Redis transaction starts with a MULTI command, and MULTI always commands to return "OK".
You can then start entering operational data, and each action command goes into the queue.
Finally execexecutes the command in the queue.
such as this:
> MULTIOK> INCR fooQUEUED> INCR barQUEUED> EXEC1) (integer) 12) (integer) 1
What if an error occurs in the transaction?
First we divide the errors in the transaction into two categories:
- An error was found before entering the queue, such as a syntax error for the command.
- exec discovers errors after execution, such as the operation of two different data types performed on the same key.
The first is a good understanding, as shown in the example above, when successfully entering the queue will immediately return "QUEUED".
If it fails to enter the queue, the entire transaction is invalidated, prompting "Transaction discarded because of previous errors."
With regard to the error that occurs after exec executes, any successful entry into the queue will be executed, even if there is a failed command in the same thing, the remaining commands will be executed .
This surprises people who have used relational databases, why does Redis not support roll back?
The two-point statement on this website:
Redis commands can fail only if called with a wrong syntax (and the problem are not detectable during the command queueing) , or against keys holding the wrong data type:this means, practical terms a failing command is the result of a pro Gramming errors, and a kind of error are very likely to being detected during development, and not in production.
Redis is internally simplified and faster because it does isn't need the ability to roll back.
Some people say that not supporting roll back will cause various bugs. But it needs to be understood that roll-back is not intended to solve programming-level errors.
Furthermore, there are only two possible causes of command failure:
- Syntax error
- Performed an operation that does not match the data type of key
With this in mind, the roll-back has little meaning, and Redis prefers to stay concise and efficient without backing roll.
Discard transaction
The DISCARD can be used as a discard current transaction and restore the connection state to a normal state.
Here's how to use it:
> SET foo 1OK> MULTIOK> INCR fooQUEUED> DISCARDOK> GET foo"1"
Atomic Nature
Check-and-set (CAS) Operations often occur in conditions of normality.
Redis provides watch to observe the change of key.
When an observed key changes before Exec executes, the entire transaction terminates and returns nil, and the observation of that key ends.
When I first touched watch, I felt it was very obscure. Can't you add a display lock or something?
Fortunately, given the full description of the website, first assume that Redis does not provide incr, we now want to simulate an incremental operation:
val = GET mykeyval = val + 1SET mykey $val
There is no problem when a client is doing this, but there is a condition when more than one client is doing this.
For example, A and B two client simultaneously get MyKey, get 10, so two execution result is 11 instead of 12.
After joining Watch:
WATCH mykeyval = GET mykeyval = val + 1MULTISET mykey $valEXEC
If there is something else between watch and exec that changes the observed key, the transaction will fail.
If you want this transaction to succeed, you need to execute it in a loop, which is, of course, a locking way.
In fact, multiple client access to the same key conflict is not common, see the specific situation to operate it.
Accordingly, there are also unwatch that can be used to release all observed keys.
For example, the INCR within a transaction will execute successfully:
WATCH keyUNWATCH keyMULTIINCR keyEXEC
Redis-Transactional operations