Redis05: transaction processing practice

Redis transaction introduction


Redis adopts the optimistic locking method for transaction control. It uses the watch command to see the given key. When exec(t commits the transaction), if the monitored key is valid for the whole connection, such as disconnecting the connection, the supervisor and transaction will be automatically cleared. Of course, the exec, discard and unwatch commands will clear all monitoring in the connection

Basic instruction

multi open transaction

exec commit transaction

discard cancel transaction

watch monitoring. If the monitored value changes, the transaction submission will fail

unwatch cancel monitoring

Redis ensures that all commands in a transaction are executed or not executed (atomicity). If the client is disconnected before sending the EXEC command, redis will empty the transaction queue and all commands in the transaction will not be executed. Once the client sends the EXEC command, all commands will be executed. Even if the client is disconnected, it doesn't matter, because all commands to be executed have been recorded in redis.

Redis transaction control practice

exec commit transaction

Simulated transfer, tony 500, jack 200, tony to Jack 100.> set tony 500
OK> set jack 200
OK> mget tony jack
1) "500"
2) "200"> multi #Open transaction
OK> decrby tony 100 #All instruction operations are queued
QUEUED> incrby jack 100
QUEUED> mget tony jack
QUEUED> exec  #Commit transaction
1) (integer) 400
2) (integer) 300
3) 1) "400"
   2) "300"> mget tony jack
1) "400"
2) "300">

discard cancel transaction

Note that the redis transaction is too simple. Instead of rolling back, it has to be cancelled.> mget tony jack
1) "400"
2) "300"> multi
OK> incrby jack 100
QUEUED> discard
OK> get jack
"300"> exec
(error) ERR EXEC without MULTI

When an incorrect instruction occurs, the transaction will also be cancelled automatically.> mget tony jack
1) "400"
2) "300"> multi
OK> incrby jack 100
QUEUED> abcd
(error) ERR unknown command `abcd`, with args beginning with:> get jack
QUEUED> exec
(error) EXECABORT Transaction discarded because of previous errors.> get jack

Second kill ticket grabbing transaction

Based on a second kill and rush purchase case, demonstrate the optimistic lock mode of redis, for example

Step 1: open client 1 and perform the following operations> set ticket 1
OK> set money 0
OK> watch ticket		#Optimistic lock. Observe the value. If the value changes, the transaction fails
OK> multi				#Open transaction
OK> decr ticket
QUEUED> incrby money 100

Step 2: open client 2 and perform the following operations. Before client 1 submits the transaction, client 2 buys the ticket> get ticket
"1"> decr ticket
(integer) 0

Step 3: return to client 1: commit the transaction and check the value of ticket> exec
(nil) #Execute transaction, failed> get ticket
"0"> unwatch #Cancel monitoring

Jedis client transaction operations

Conduct transaction test based on Jedis, and the code is as follows:

package com.jt;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

public class JedisTransactionTests {

    public void testTransaction(){
        Jedis jedis=new Jedis("",6379);
        //To implement the operation, tony transfers 100 to jack
        //Open transaction
        Transaction multi = jedis.multi();
        //Perform business operations
        try {
            multi.decrBy("tony", 100);
            multi.incrBy("jack", 100);
            int n=100/0;//Simulation anomaly
            //Commit transaction
        }catch(Exception e) {
            //An exception occurred to cancel the transaction
        String tonyMoney=jedis.get("tony");
        String jackMoney=jedis.get("jack");

Jedis client second kill operation practice

package com.jt.demos;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Response;
import redis.clients.jedis.Transaction;

import java.util.List;

 * redis Second kill exercise:
 * Simulate that both threads rush to buy the same ticket (consider music lock)
public class SecondKillDemo02 {

      public static void secKill(){
          Jedis jedis=new Jedis("",6379);
          String ticket = jedis.get("ticket");
              throw new RuntimeException("No inventory");
          Transaction multi = jedis.multi();
          try {
              multi.incrBy("money", 100);
              List<Object> exec = multi.exec();
          }catch (Exception e){
          }finally {
      public static void main(String[] args) {
          Jedis jedis=new Jedis("",6379);

          Thread t1=new Thread(()->{
          Thread t2=new Thread(()->{

Keywords: Database Redis

Added by Poomerio on Tue, 12 Oct 2021 03:52:38 +0300