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 ~