package com.csw.shuanfa.CodeImprove.redlockThread;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import java.time.Duration;
import java.util.Collections;
import java.util.List;
@SpringBootTest
@Slf4j
public class RedisTransaction {
@Autowired
private StringRedisTemplate stringRedisTemplate;
private String key = "key";
private String value = "value";
private int minutes = 1;
@Test
public void test() {
//set-key 非原子性
stringRedisTemplate.opsForValue().set(key + "1", value);
stringRedisTemplate.expire(key + "1", Duration.ofMinutes(minutes));
//set-key 原子性【【推荐】】
stringRedisTemplate.opsForValue().set(key + "2", value, Duration.ofMinutes(minutes));
//set-key 原子性-用于分布式锁【【推荐】】
stringRedisTemplate.opsForValue().setIfAbsent(key + "3", value, Duration.ofMinutes(minutes));
//increment 非原子性
stringRedisTemplate.opsForValue().increment(key + "4");
stringRedisTemplate.expire(key + "4", Duration.ofMinutes(minutes));
//increment-原子性-lua【设置自增,失效时间一分钟,只有第一次才会更新时间】
String luaScript = "local count = redis.call('incr', KEYS[1]); if count == 1 then redis.call('expire', KEYS[1], ARGV[1]) end; return count;";
RedisScript<Long> redisScript = new DefaultRedisScript<>(luaScript, Long.class);
Long result = stringRedisTemplate.execute(redisScript, Collections.singletonList(key + "5"), String.valueOf(60));
//原子性-非批量【【推荐】】替换lua###################################################################################################
Long st6 = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
stringRedisTemplate.execute(new SessionCallback<List<Object>>() {
@Override
public <K, V> List<Object> execute(RedisOperations<K, V> operations) {
try {
//开启原子性
operations.multi();
// 以下是放入事务队列中的多个操作
for (int i = 0; i < 100; i++) {
//多个非原子性操作
operations.opsForValue().increment((K) (key + "6"));
operations.expire((K) (key + "6"), Duration.ofMinutes(minutes));
// if (i == 5) {
// throw new RuntimeException();
// }
}
//事务返回结果
operations.exec();
} catch (Exception e) {
// 捕获到异常后手动回滚事务
operations.discard();
throw e;
}
return null;
}
});
}
log.info("耗时execute用事务(ms):{}", (System.currentTimeMillis() - st6));
//非原子性-非批量【证明不开启原子性,他是不具有原子性的】
Long st7 = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
stringRedisTemplate.execute(new SessionCallback<List<Object>>() {
@Override
public <K, V> List<Object> execute(RedisOperations<K, V> operations) {
// 以下是放入事务队列中的多个操作
for (int i = 0; i < 100; i++) {
//多个非原子性操作
operations.opsForValue().increment((K) (key + "7"));
operations.expire((K) (key + "7"), Duration.ofMinutes(minutes));
// if (i == 5) {
// throw new RuntimeException();
// }
}
return null;
}
});
}
log.info("耗时execute不用事务(ms):{}", (System.currentTimeMillis() - st7));
//非原子性-批量处理【证明管道里面开启原子性是无效的】
Long st8 = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
stringRedisTemplate.executePipelined(new SessionCallback<List<Object>>() {
@Override
public <K, V> List<Object> execute(RedisOperations<K, V> operations) {
try {
//开启原子性
operations.multi();
// 以下是放入事务队列中的多个操作
for (int i = 0; i < 100; i++) {
//多个非原子性操作
operations.opsForValue().increment((K) (key + "8"));
operations.expire((K) (key + "8"), Duration.ofMinutes(minutes));
// if (i == 5) {
// throw new RuntimeException();
// }
}
//事务返回结果
operations.exec();
} catch (Exception e) {
// 捕获到异常后手动回滚事务
operations.discard();
throw e;
}
return null;
}
});
}
log.info("耗时executePipelined用事务(ms):{}", (System.currentTimeMillis() - st8));
//非原子性-批量【【推荐】】性能高###################################################################################################
Long st9 = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
stringRedisTemplate.executePipelined(new SessionCallback<List<Object>>() {
@Override
public <K, V> List<Object> execute(RedisOperations<K, V> operations) {
// 以下是放入事务队列中的多个操作
for (int i = 0; i < 100; i++) {
//多个非原子性操作
operations.opsForValue().increment((K) (key + "9"));
operations.expire((K) (key + "9"), Duration.ofMinutes(minutes));
// if (i == 5) {
// throw new RuntimeException();
// }
}
return null;
}
});
}
log.info("耗时executePipelined不用事务(ms):{}", (System.currentTimeMillis() - st9));
}
}
redis事务/原子性操作
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...