当前位置:网站首页>Redis transaction
Redis transaction
2022-07-19 08:05:00 【Program three two lines】
One 、 summary
redis A transaction is a separate isolation operation , All commands in the transaction are serialized 、 Execute in order . The transaction execution process will not be interrupted by the command requests sent by other clients , The main function of transactions is to concatenate multiple commands to prevent other commands from jumping in the queue
Two 、 Transaction execution command
redis and mysql Transactions are fundamentally different ,redis From input Multi Command start , All the entered commands will enter the command queue in turn , But will not execute , Until the execution process is entered Exec after ,redis The previous commands in the command queue will be executed successively , In the process of team formation, you can go through discard Give up team , As shown in the following figure

Demonstrate alignment

Demonstrate giving up teaming

3、 ... and 、 Transaction exception error
First error : An error occurred in a command during the formation stage , The entire queue will be canceled during execution


The second mistake : An error occurred in a column in the queue during execution , Only those with errors will not be executed , No rollback , Other normal execution


Four 、 Transaction conflict and handling
1、 Overview of transaction conflicts
immediately 618 了 、 Suppose a scene : Many people have your account and only 10000, At the same time 618 Rush purchase , Three requests were sent at the same time
A request wants to reduce the amount 8000
A request wants to reduce the amount 5000
A request wants to reduce the amount 1000
These three requests are sent at the same time , If the implementation is successful , Then the balance of the account becomes 10000-8000-5000-1000 = -4000, At this time, the account balance becomes negative , Obviously, this is very unreasonable in real life .

At this time, all we can think of is locking .
2、 Resolve transaction conflicts
2.1、 Pessimistic locking
seeing the name of a thing one thinks of its function , It's a very pessimistic kind , Like wishful thinking. Every time I go to get the data, I always think that others will change , So every time I get the data, I lock it , So that if people want to take this data, they will block Until it gets the lock . There are many lock mechanisms used in traditional relational databases , For example, line locks. , Table lock, etc. , Read the lock , Write locks, etc. , It's all locked before the operation .

2. 2、 Optimism lock

And pessimistic lock lock-in will not lock when getting data , Because he believes that the world is beautiful , No one else will modify , But out of rigor, I will check whether it has been modified at the moment of changing the data . You can use mechanisms like version numbers . Optimistic lock is suitable for multi read applications , This can improve throughput .Redis It's using this check-and-set The mechanism implements the .
Optimistic lock is more efficient than pessimistic lock , Because the pessimistic lock will be locked every time, while the optimistic lock just checks whether the version number is the version number just obtained when modifying the data, so it cannot be implemented , It's about execution .
3、redis in WATCH
In execution multi Before , Execute first watch key1 [key2], You can watch one ( Or more ) key , If before the transaction is executed ( Or these ) key Altered by other orders , Then the business will be interrupted .
example :
Set a key to balance The value is 10 String type data .
Use watch monitor
Open two clients , Start the transaction pair after monitoring separately balance Conduct +100 operation , Once the client submits first, it will succeed , Client 2 submission will fail , This is it. WAYCH Monitor transactions , Prevent transaction conflicts .
Client 1 : Successful execution of transaction

Client 2 : Failed to execute transaction

summary
Concurrency problems are easy to occur in practical applications 、 So we're going to be here redis Locking in transactions solves the conflict problem of transactions
stay redis Used in check-and-set Optimistic locking mechanism realizes transaction
redis Optimistic lock use in watch Command to achieve
4、redis Case of transaction locking mechanism --- seckill
4.1、 summary
A seckill mainly consists of two operations: reducing the number of goods and recording successful users
/**
* Whether the second kill is successful
* @param uid Second kill users
* @param pid goods id
* @return Seckill success
*/
public Boolean doKill(String uid,Integer pid){
//1.uid pid Judge not empty
if(uid == null || pid == null){
return false;
}
//2. Connect jedis
Jedis jedis = new Jedis("127.0.0.1","6379");
//3. Splicing key
// stock key
String kcKey = "kc"+pid;
// user key
String userKey = "user"+pid;
//4. Judge whether the inventory is empty
String kc = jedis.get(kcKey;
if(kc == null){
jedis.close();
return false;
}
//5. Judge whether the user repeats the second kill
if(jedis.sismember(userKey,uid)){
jedis.close();
return false;
}
//6. The stock is greater than 0
if(Integer.parseInt(kc)<=0){
jedis.close();
return false;
}
//7. seckill
jedis.decr(kcKey);
jedis.sadd(userKey,uid);// user id When the value of set Type of
jedis.close();
return true;
}4.2、 Concurrency issues
Using tools ab Simulate concurrency or jmeter There are two problems when simulating the request
1、 Connection timeout ( A lot of requests redis Lead to blocking )
Solution : Lead into the connection pool , Customize a connection pool tool class as follows
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class JedisPoolUtils {
private static volatile JedisPool jedisPool = null;
private JedisPoolUtils(){
}
// Lazy double check lock , Thread safety
public static JedisPool getJedisPoolInstance() {
if(null == jedisPool) {
synchronized (JedisPoolUtils.class) {
if(null == jedisPool) {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(200);
poolConfig.setMaxIdle(32);
poolConfig.setMaxWaitMillis(100*1000);
poolConfig.setTestOnBorrow(true);
jedisPool = new JedisPool(poolConfig,"192.168.235.128",6379);
}
}
}
return jedisPool;
}
public static void release(JedisPool jedisPool, Jedis jedis) {
if(null != jedis) {
jedisPool.returnResourceObject(jedis);
}
}
}The spike code above has been changed
Jedis jedis = new Jedis("127.0.0.1","6379");
change

2、 Concurrent error problem , Inventory becomes negative
Solve by optimistic lock , Change the above code to add monitoring and transactions

4.3、 Inventory remaining problems
The oversold problem can be solved through the above , But there will be inventory The remaining questions , Because optimistic locking is controlled by modifying this version , For example 10 After monitoring users, the version is changed to 1 The user versions changed later are inconsistent and will not be operated, so the remaining
resolvent , adopt lua Script solution
lua summary
lua It will be complex or multi-step redis The operation is written into a script , Submit to redis perform , Reduce repeated connections redis Times to improve performance ,lua Script similar redis Business , It has certain atomicity , Will not be interrupted by other orders , You can do some redis Transactional operations , however redis Of lua Script only in redis2.6 The above version can be used , utilize lua The script solves the oversold problem , It's actually using redis The single thread feature uses task queues to solve the problem of task concurrency
Implementation class


4.4、 Expand
For the second kill operation spring boot ,redis template It can also be realized
/**
* adopt redis Business Achieved seckill
* @param skuCode Commodity code
* @param buyNum Purchase quantity
* @return Purchase quantity
*/
@Service
public class GoodsServiceImpl {
@Autowired
StringRedisTemplate redisTemplate;
//redis For any illegal value , All called ERR. use RedisTemplate Serialized numbers cannot be converted
// Use GenericToStringSerializer、StringRedisSerializer Serializer , You can use increment Method The number saved is 10 instead of "10" character string
/* 1 redisTemplate.excute(SessionCallback sessionCallback) It's for the execution of affairs api
* 2 So to achieve SessionCallback To achieve redis Business .
* 3 If direct adopt redisTemplate Execute the transaction command Will report a mistake */
public Long flashSellByRedisWatch(String skuCode,int num){
SessionCallback<Long> sessionCallback = new SessionCallback<Long>() {
@SuppressWarnings("unchecked")
@Override
public Long execute(RedisOperations operations) throws DataAccessException {
int result = num;
//redis Optimism lock
operations.watch(skuCode);
ValueOperations<String, String> valueOperations = operations.opsForValue();
String goodNumStr = valueOperations.get(skuCode);
Integer goodNum = Integer.valueOf(goodNumStr);
// Mark the beginning of a transaction block .
// Multiple commands in a transaction block are put into a queue in sequence ,
// Finally by EXEC Command atomicity (atomic) Carry out smoothly .
operations.multi();
if (goodNum>=num) {
valueOperations.increment(skuCode, 0-num);// A negative number means you need to reduce the number of goods
}else{
result = 0;
}
// The result set of multiple command execution
List exec = operations.exec();
if(exec.size()>0){
System.out.println(" Successful implementation : "+exec);
}
return (long) result;
}
};
return redisTemplate.execute(sessionCallback);
}
}边栏推荐
- 在线问题反馈模块实战(五):实现对通用字段内容自动填充功能
- Look back at the paper after reading the code: yolov3 reread
- Pytoch notes (1)
- Modify scroll bar style
- 175. Combine two tables (MySQL database connection)
- Transferring multiple pictures is the judgment of empty situation.
- RNN convolutional neural network
- 【刷题篇】完全平方数
- 分叉币的发展史及价值|ETH、BCH、BSV 2020-03-08
- FMC sub card: 4-way sfp+ 10 Gigabit optical fiber network FMC sub card
猜你喜欢

STM32F103C8T6硬件IIC控制4针0.96寸OLED显示屏

【C语言】自定义类型详解:结构体、枚举、联合

From the casino logic, analyze the investment value of platform currency 2020-03-03

Use of fiddler packet capturing tool

xgboos-hperopt

看完代码回首看论文:YOLOv3重读

网站APP数据库里的用户信息被泄露篡改怎么办

【MySQL】 事务:事务基础知识、MySQL事务实现原理、事务日志 redolog & undolog 详解

Redis 跳跃表实现原理 & 时间复杂度分析

Pytoch notes (3)
随机推荐
Discussion sur la technologie RISC - V
Facial key point detection CNN
Yolov5 label and establish your own data set
Use of mongodb
YOLOV5-打标签建立自己的数据集
如何在 Jenkins Pipeline 中使用curl 并处理响应结果
@How can conditionalonmissingbean cover beans in third-party components
Is there any cumulative error in serial communication and the requirements for clock accuracy
Pytoch notes (3)
[MySQL] mvcc: correctly understand mvcc and its implementation principle
【MySQL】 锁机制:InnoDB引擎中锁分类以及表锁、行锁、页锁详解
[JVM] heap memory, escape analysis, on stack allocation, synchronous omission, scalar replacement details
175. 组合两个表(MySQL数据库连接)
Virtual machine stack of [JVM]
FMC sub card: 8-channel 125msps sampling rate 16 bit AD acquisition sub card
[MySQL] lock mechanism: detailed explanation of lock classification, table lock, row lock and page lock in InnoDB engine
本地存储 sessionStorage
[C # variable constant keyword] - variable constants and keywords in C #
《痞子衡嵌入式半月刊》 第 58 期
Using PCA to simplify data