[Redis series] redis learning 6, redis transaction processing and monitoring transactions
written in front
The transactions we have learned are guaranteed to be atomic, but executing multiple instructions in a redis transaction does not guarantee atomicity
The nature redis transactions1621a3978a971c
It is a collection of commands. All commands in a transaction will be serialized. In the process of transaction execution, commands are executed in order. They have
- Disposable
- sequential
- exclusivity
transactions have no concept of isolation level
redis transaction, the command is executed like this
The command is placed in the transaction and is not executed immediately, but will be executed when the command is executed, triggered by exec
Redis guarantees atomicity for a single instruction, but transactions do not guarantee atomicity
The flow of executing a transaction looks like this:
- multi open transaction
- Enqueue various commands
- exec execute transaction
open transaction
MULTI
open a transaction
EXEC
Execute the instructions in the transaction
After executing the transaction, you need to use the transaction again, then you need to open the transaction 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 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"
abandon business
DISCARD
Abandon the most 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)
transaction error
There are two types of transaction errors:
- compile error
- runtime error
compile error
The code is written incorrectly and cannot be compiled. At this time, all the instructions written in the transaction fail to be executed.
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 changsha
QUEUED
127.0.0.1:6379(TX)> set dream xxx
QUEUED
127.0.0.1:6379(TX)> setget hahaha # 指令不存在,编译不通过,直接报错
(error) 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)
Once a compilation error occurs, all instructions in the transaction will not be executed
runtime error
When the program is running, there is a problem with a specified logic, which only affects the execution of this execution, and this instruction will run out of exception, without affecting 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 指令用法正确,只不过 name 是字符串,运行的时候,是无法执行通过的
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 name
"xiaozhu"
According to the above results, the usage of the incr
instruction is correct, but incr
can only operate on numbers, and name
is a string that cannot be incremented, so an error is reported at runtime, and the transaction does not affect the execution of other instructions
watch monitoring of redis
watch monitoring, we can talk about optimistic locking and pessimistic locking
optimistic lock :
- Very optimistic, I think that there will be no problem at any time, so it will not be locked. When updating the data, I will judge if the data has changed during this period.
- Optimistic locking will first obtain a version of the underlying data
- When updating the data, it will compare whether the version has changed. If it has changed, the update will fail. If there has been no change, the data will be updated.
Pessimistic Lock :
- Very pessimistic, whenever you think there will be a problem, you have to lock it
Monitoring test of redis
Use watch to lock and simulate bank withdrawal
- money account has 2000
- outer 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
Start the test to simulate multiple threads to operate
redis client 1
- money account has 2000
- outer account has 500
- The money account gives 500 to the outer account, and the execution has not yet started
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
The transaction operation of client 1 has not yet started, client 2 has performed the following operations
127.0.0.1:6379> set money 10000
OK
127.0.0.1:6379> set money 10000
OK
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"
It is found that when client 1 executes exec , it is a nil, indicating that the change failed, because the watch monitors that the money has changed, so the transaction execution fails
unwatch
It is found that the transaction execution failed, you need to use the command unwatch to release 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
QUEUED
127.0.0.1:6379(TX)> INCRBY outer 1000
QUEUED
127.0.0.1:6379(TX)> exec
1) (integer) 9000
2) (integer) 1500
This is how redis implements optimistic locking, and the general usage scenario will be put into the seckill system for application
References:
Welcome to like, follow, favorite
Friends, your support and encouragement are the motivation for me to persist in sharing and improve quality
Okay, here it is this time
Technology is open, and our mentality should be open. Embrace change, live in the sun, and move forward.
I'm little devil boy Nezha , welcome to like, follow and favorite, see you next time~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。