Redis事务简介

目录

Redis事务简介

基本指令

Jedis 客户端事务操作


 

Redis事务简介

  • 概述
  • 事务是一个业务,也可以看成是一个逻辑工作单元,是为了保证业务的完整,数据的正确而推出的一种控制机制,原则上来讲,事务必须要满足ACID四个特性(原子性,一致性,隔离性,持久性),在多个事务
  • 在并发执行,为更好保证事务的四个特性的实现,通常会对事务加锁,Redis为了性能,采用了乐观锁方式进行事务控制,它使用watch命令监视给定的key,当exec(提交事务)的时候,如果监视的key从调用watch后发生过变化,则整个事务会失败。也可以调用watch多次监视多个key。注意watch的key是对整个连接有效的,如果连接断开,监视和事务都会被自动清除。当然exec,discard,unwatch命令都会清除连接中的所有监视。

基本指令

  1. multi 开启事务
  2. exec 提交事务
  3. discard 取消事务
  4. watch 监控,如果监控的值发生变化,则提交事务时会失败,类似乐观锁
  5. unwatch 去掉监控
  6. Redis保证一个事务中的所有命令要么都执行,要么都不执行(原子性)。如果在发送EXEC命令前客户端断线了,则Redis会清空事务队列,事务中的所有命令都不会执行。而一旦客户端发送了EXEC命令,所有的命令就都会被执行,即使此后客户端断线也没关系,因为Redis中已经记录了所有要执行的命令。
  7. 当出现错误指令时,事务也会自动取消。

Jedis 客户端事务操作

package com.jt.transactionTestsDemo;


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

import java.util.List;

/**
 * redis秒杀练习:
 * 模拟两个线程都去抢购同一张票(考虑乐关锁)
 */
public class SecondKillDemo02 {

    public static void secKill(){
        Jedis jedis=new Jedis("192.168.126.129",6379);
        jedis.watch("ticket","money");
        String ticket = jedis.get("ticket");
        if(ticket==null||Integer.valueOf(ticket)==0)
            throw new RuntimeException("已无库存");
        Transaction multi = jedis.multi();
        try {
            multi.decr("ticket");
            multi.incrBy("money", 100);
            List<Object> exec = multi.exec();
            System.out.println(exec);
        }catch (Exception e){
            e.printStackTrace();
            multi.discard();
        }finally {
            jedis.unwatch();
            jedis.close();
        }
    }
    public static void main(String[] args) {
        Jedis jedis=new Jedis("192.168.126.129",6379);

        jedis.set("ticket","1");
        jedis.set("money","0");
        Thread t1=new Thread(new Runnable() {
            @Override
            public void run() {
                secKill();
            }
        });Thread t2=new Thread(new Runnable() {
            @Override
            public void run() {
                secKill();
            }
        });
        Thread t3=new Thread(()->{
            secKill();
        });
        Thread t4=new Thread(()->{
            secKill();
        });
        t1.start();

        t3.start();
        t4.start();
        t2.start();
    }
}
package com.jt;

import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

public class JedisTransactionTests {
    @Test
    public void testJedisTransaction(){
        Jedis jedis = new Jedis("192.168.126.129",6379);
        jedis.set("tony", "500");
        jedis.set("tom", "300");
        //实现操作,tony转账100给jack
        //开启事务
        Transaction multi = jedis.multi();
        //执行业务操作
        try {
            multi.decrBy("tony", 100);
            multi.incrBy("jack", 100);
            int n=100/0;//模拟异常
            //提交事务
            multi.exec();
        }catch(Exception e) {
            //出现异常取消事务
            multi.discard();
        }
        String tonyMoney=jedis.get("tony");
        String jackMoney=jedis.get("jack");
        System.out.println("tonyMoney="+tonyMoney);
        System.out.println("jackMoney="+jackMoney);
        jedis.close();

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值