目录
1. 事务简介:
-> 1.1 必须满足: ACID四个特性(原子性,一致性,隔离性,持久性)
-> 1.2 简单理解: 一个业务,也可以看成是一个逻辑工作单元;
2. redis 操作事务的基本指令
-> 指令:
-> 图式:
3. 模拟多事务操作(watch乐观锁)
3.1 不开启乐观锁watch操作
-> 按照执行指令提交的先后顺序
3.2 开启乐观锁watch操作
-> 3.2.1 A事务 先不提交
-> 3.2.2 B事务 直接提交后A在提交
-> 3.2.3 然后操作A事务提交
4. Jedis代码
4.1 (事务操作)
4.2 事务 + 乐观锁
1. 事务简介:
-> 1.1 必须满足: ACID四个特性(原子性,一致性,隔离性,持久性)
-> 1.2 简单理解: 一个业务,也可以看成是一个逻辑工作单元;
是为了保证业务的完整,数据的正确而推出的一种控制机制
2. redis 操作事务的基本指令
-> 指令:
- multi 开启事务
- exec 提交事务
- discard 取消事务
- watch 监控,如果监控的值发生变化,则提交事务时会失败
- unwatch 去掉监控
-> 图式:
3. 模拟多事务操作(watch乐观锁)
3.1 不开启乐观锁watch操作
-> 按照执行指令提交的先后顺序
3.2 开启乐观锁watch操作
-> 3.2.1 A事务 先不提交
-> 3.2.2 B事务 直接提交后A在提交
-> 3.2.3 然后操作A事务提交
4. Jedis代码
4.1 (事务操作)
package cn.pzy.transactionals;
import cn.pingzhuyan.jedisPool.JedisDataSourceLazy;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import static cn.pingzhuyan.jedisPool.JedisDataSourceLazy.PRIVATE_KEY;
public class JedisTransactionTests {
@Test
public void testTransactionals() {
Transaction multi = null;
//try里面的内容不重要 就是基础的jedis连接池
try (Jedis jedis = JedisDataSourceLazy.lazyConnection(PRIVATE_KEY)) {
jedis.set("aaa", "100");
jedis.set("bbb", "200");
//实现操作,aaa给bbb 100
// 结果是 aaa 0 bbb 300
//开启事务
multi = jedis.multi();
//执行业务操作
multi.decrBy("aaa", 100);
multi.incrBy("bbb", 100);
/*模拟异常 开启则报错, 如下图*/
// int n = 1 / 0;
//提交事务
multi.exec();
String aaa = jedis.get("aaa");
String bbb = jedis.get("bbb");
System.out.println("aaa=" + aaa);
System.out.println("bbb=" + bbb);
} catch (Exception e) {
if (multi != null) {
System.out.println("事务处理中出现异常, 取消执行队列!!!");
System.out.println(e.getMessage());
multi.discard();
}
}
}
}
4.2 事务 + 乐观锁
[仍需测试, 感觉有点小问题]
package cn.pzy.transactionals;
import cn.pingzhuyan.jedisPool.JedisDataSourceLazy;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import java.util.List;
import java.util.Objects;
import static cn.pingzhuyan.jedisPool.JedisDataSourceLazy.PRIVATE_KEY;
public class Demo01 {
public static void secKill() {
Jedis jedis = null;
Transaction multi = null;
//try里面的内容不重要 就是基础的jedis连接池
try {
jedis = JedisDataSourceLazy.lazyConnection(PRIVATE_KEY);
jedis.watch("ticket", "money");
String ticket = jedis.get("ticket");
if (ticket == null || Integer.parseInt(ticket) == 0) {
System.out.println("已无库存!!!");
throw new RuntimeException("已无库存");
}
multi = jedis.multi();
multi.decr("ticket");
multi.incrBy("money", 100);
List<Object> exec = multi.exec();
System.out.println(exec);
// if (exec == null || Objects.equals(exec.size(), 0)) {
// System.out.println("无命令执行!!!");
// throw new RuntimeException("无命令执行");
// }
} catch (Exception e) {
e.printStackTrace();
if (multi != null) {
System.out.println("取消事务!!!");
multi.discard();
}
} finally {
if (jedis != null) {
System.out.println("锁和池释放!!!");
jedis.unwatch();
jedis.close();
}
}
}
public static void main(String[] args) throws InterruptedException {
Jedis jedis = JedisDataSourceLazy.lazyConnection(PRIVATE_KEY);
jedis.set("ticket", "2");
jedis.set("money", "0");
new Thread(() -> {
secKill();
System.out.println("执行1");
}).start();
Thread.sleep(2);
new Thread(() -> {
secKill();
System.out.println("执行2");
}).start();
}
}