This is the 21st day of my participation in the August Text Challenge.More challenges in August
【Redis series 】 Redis learning 6, Redis transaction processing and monitoring transactions
Writing in the front
We have learned that transactions are guaranteed atomicity, but redis transactions execute multiple instructions, is not guaranteed atomicity
The nature of redis transactions
It’s a set of commands, all the commands in a transaction are serialized, and during the execution of the transaction, the commands are executed in sequence, they have
- A one-time
- sequential
- exclusive
Redis transactions have no concept of isolation levels
In redis transactions, commands are executed like this
The command is placed in a transaction and is not executed immediately, but is executed when the command is initiated, which is triggered by exec
Redis guarantees atomicity for single instructions, but not for transactions
The process of executing a transaction looks like this:
- Multi Start transaction
- All orders to join the ranks
- Exec executes transactions
Open the transaction
MULTI
Start a transaction
EXEC
Execute the instructions in the transaction
After the transaction is executed and needs to be used again, the transaction needs to be started again
127.0.0.1:6379> MULTI OK 127.0.0.1:6379(TX)> set k1 v1 QUEUED 127.0.0.1:6379(TX)> set k2 v2 QUEUED 127.0.0.1:6379(TX)> set k2 v2 QUEUED 127.0.0.1:6379(TX)> Set name xiaozhu QUEUED 127.0.0.1:6379(TX)> set age 19 QUEUED 127.0.0.1:6379(TX)> set hobby paly QUEUED 127.0.0.1:6379(TX)> exec 1) OK 2) OK 3) OK 4) OK 5) OK 127.0.0.1:6379> MULTI OK 127.0.0.1:6379(TX)> set city changsha QUEUED 127.0.0.1:6379(TX)> get city QUEUED 127.0.0.1:6379(TX)> exec 1) OK 2) "changsha"Copy the code
Give up the transaction
DISCARD
Abandon the recently opened transaction
127.0.0.1:6379> flushdb OK 127.0.0.1:6379> MULTI OK 127.0.0.1:6379(TX)> set name xiaozhu QUEUED 127.0.0.1:6379(TX)> set Age 10 QUEUED 127.0.0.1:6379(TX)> set city Beijing QUEUED 127.0.0.1:6379(TX)> DISCARD OK 127.0.0.1:6379> get city (nil) 127.0.0.1:6379 > get name (nil)Copy the code
Transaction error
Transaction errors fall into two categories:
-
Compilation error
-
Runtime error
Compilation error
Code compilation error, unable to compile, at this time the instructions written inside the transaction, all failed to execute
127.0.0.1:6379> flushdb OK 127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> set name xiaozhu QUEUED 127.0.0.1:6379(TX)> set Age 10 QUEUED 127.0.0.1:6379(TX)> Set hobby play QUEUED 127.0.0.1:6379(TX)> set City QUEUED 127.0.0.1:6379(TX)> set city QUEUED 127.0.0.1:6379(TX)> Set dream XXX QUEUED 127.0.0.1:6379(TX)> setget hahaha # ERR unknown command 'setget', with args beginning with: `hahaha`, 127.0.0.1:6379(TX)> exec (error) EXECABORT Transaction discarded because of previous errors. 127.0.0.1:6379> get city (nil)Copy the code
If a compilation error occurs, none of the instructions in the transaction are executed
Runtime error
When the program runs, the problem of a specified logic only affects the execution of this instruction, and this instruction will run out of exception, and does not affect the execution of other instructions in the transaction
127.0.0.1:6379> flushdb OK 127.0.0.1:6379> set name xiaozhu OK 127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> get name QUEUED 127.0.0.1:6379(TX)> INCR name # INCR Yes QUEUED 127.0.0.1:6379(TX)> set age 29 QUEUED 127.0.0.1:6379(TX)> set hobby play QUEUED 127.0.0.1:6379(TX)> exec 1) "xiaozhu" 2) (error) ERR value is not an integer or out of range 3) OK 4) OK 127.0.0.1:6379> get hobby "play" 127.0.0.1:6379 > get the name "xiaozhu"Copy the code
According to the above results, the use of incR instruction is correct, but INCR can only operate on numbers. Name is a string and cannot be incremented. Therefore, errors are reported during operation, and the execution of other instructions is not affected in the transaction
Redis watch monitor
Watch: Optimistic locks and pessimistic locks
Optimistic locking:
- I’m optimistic, I think it’s never going to go wrong, so I’m not going to lock it, so I’m going to update the data and I’m going to look at what happens to the data in the meantime, right
- Optimistic locks first fetch a version of the underlying data
- When updating data, the system compares whether the version has changed. If the version has changed, the update fails. If the version has not changed, the system updates the data
Pessimistic locks:
- Very pessimistic, whenever you think something’s going to go wrong, lock it up, right
Redis monitoring tests
Use watch to lock to simulate bank withdrawal
- The money account has 2000
- Outer’s account has 500
- Money account to Outer account 500
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> set money 2000
OK
127.0.0.1:6379> set outer 500
OK
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> DECRBY money 500
QUEUED
127.0.0.1:6379(TX)> INCRBY outer 500
QUEUED
127.0.0.1:6379(TX)> exec
1) (integer) 1500
2) (integer) 1000
Copy the code
Start testing to simulate multiple threads to operate
Redis client 1
- The money account has 2000
- Outer’s account has 500
- Money account to Outer account 500, has not been executed
127.0.0.1:6379> set money 2000
OK
127.0.0.1:6379> set outer 500
OK
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> DECRBY money 500
QUEUED
127.0.0.1:6379(TX)> INCRBY outer 500
QUEUED
Copy the code
Before the transaction on client 1 is executed, client 2 performs the following operations
127.0.0.1:6379> set money 10000
OK
127.0.0.1:6379> set money 10000
OK
Copy the code
At this point, the exec instruction of client 1 is executed
127.0.0.1:6379(TX)> exec
(nil)
127.0.0.1:6379> get money
"10000"
Copy the code
It was found that when client 1 executed exec, it was nil, indicating that the change failed, because Watch monitored the change of money, so transaction execution failed
unwatch
If a transaction fails to be executed, run the unwatch command to remove the monitoring
127.0.0.1:6379> UNWATCH OK 127.0.0.1:6379> Watch money OK 127.0.0.1:6379> Multi OK 127.0.0.1:6379(TX)> DECRBY money 1000 Outer 1000 QUEUED 127.0.0.1:6379(TX)> exec 1) (integer) 9000 2) (integer) 1500Copy the code
This is redis to achieve optimistic lock operation, the general use of the scenario will be put into the second kill system for application
References:
redis_doc
Welcome to like, follow and favorites
Friends, your support and encouragement, I insist on sharing, improve the quality of the power
All right, that’s it for this time
Technology is open, our mentality, should be more open. Embrace change, live in the sun, and strive to move forward.
I am Nezha, welcome to like, see you next time ~