并发的修改1个字段,集群环境

用了redisson的加锁,锁10秒钟,防重(业务上防止一个用户进行多次插入,只允许插入一条)的select代码在加锁的代码外面,如果存在,就不让执行锁里面的代码。
锁里面的代码:读取某个字段(如起始价格),然后修改最终价格(随机的),插入数据表,在锁的里面执行
目前出现了几笔同一个人的重复数据,起始价格都一样,最终价格不一样
怀疑是锁里面的代码执行的数据库修改并没有随锁的释放提交,导致防重逻辑失效
请问如何规避这种问题?

以下是伪代码

这个是controller,接请求,检查该用户是否在A表插入过记录,没有差如果,执行updateFieldAndInsertRecordConcurrently

//id为用户id

if(!checkIfExisitByUserId(id)) {

updateFieldAndInsertRecordConcurrently(id);

}

//这个是其他的辅助类的方法

updateFieldAndInsertRecordConcurrently(Integer id) {

try{

RLock lock = redisClientManager.getClient().getLock("Activity_Price_Off_midAutumnLock";

lock.lock(Integer.parseInt("10"), TimeUnit.SECONDS); //redisson的锁,最多锁10s

//从B表读取价格

BigDecimal currentPrice = getCuurentPrice();

//随机一个价格,减掉

BigDeciaml randomOffPrice = getRandomOffPrice();

//最终价格

BigDecimal resultPrice = currentPrice.subtract(randomOffPrice);

//插入A记录(起始价格,随机价格,优惠后价格)

insertARecordByUserId(id, currentPrice, randomOffPrice, resultPrice ) ;

//更新B表的价格栏位

updateCurrentPrice(resultPrice);

}catch(Exception e) {}

finally {

lock.unlock();

}

}

现在A表存在两个用户的记录,比如a1,a2,起始价格(currentPrice栏位都一样),而这是业务不允许的,要求串行

脏数据见图片:三栏的含义分别是:用户,随机价格,优惠后价格

图片描述

回答:

代码不贴出来,怎么玩,在怎么也要把伪代码写出来吧
lock.lock(Integer.parseInt("10"), TimeUnit.SECONDS);这句的问题
如果有多个请求过来,比如说有人手贱多点了几次
第一个请求拿到锁后,更新数据,后面的请求会阻塞,并不过直接跳过去,等第一个请求执行完成后释放锁,后续的请求又拿到锁了,所以又执行了
应该是这样一个逻辑就ok了,同时来了多个请求,第一个请求拿到锁执行代码逻辑,后面的请求直接跳过就不会出现你的问题了
应该是你api用错了,用这个boolean tryLock()
类似代码

updateFieldAndInsertRecordConcurrently(Integer id) {

try{

RLock lock = redisClientManager.getClient().getLock("Activity_Price_Off_midAutumnLock";

if(lock.tryLock()){

//从B表读取价格

BigDecimal currentPrice = getCuurentPrice();

//随机一个价格,减掉

BigDeciaml randomOffPrice = getRandomOffPrice();

//最终价格

BigDecimal resultPrice = currentPrice.subtract(randomOffPrice);

//插入A记录(起始价格,随机价格,优惠后价格)

insertARecordByUserId(id, currentPrice, randomOffPrice, resultPrice ) ;

//更新B表的价格栏位

updateCurrentPrice(resultPrice);

}

}catch(Exception e) {}

finally {

lock.unlock();

}

}

以上是 并发的修改1个字段,集群环境 的全部内容, 来源链接: utcz.com/p/176017.html

回到顶部