debug:高并发情况下,智能退款失败(因为乐观锁了余额)
This commit is contained in:
parent
91fcd92952
commit
a88d5c407c
|
@ -100,10 +100,10 @@ public class IotServiceImpl implements IotService {
|
||||||
if (res != null && res.isNotOnline()) {
|
if (res != null && res.isNotOnline()) {
|
||||||
status = DeviceOnlineStatus.OFFLINE.getStatus();
|
status = DeviceOnlineStatus.OFFLINE.getStatus();
|
||||||
}
|
}
|
||||||
// 若是命令超时,则累加redis数据,超过1次则判断为离线
|
// 若是命令超时,则累加redis数据,超过2次则判断为离线
|
||||||
else if (res == null || res.isCmdTimeout()) {
|
else if (res == null || res.isCmdTimeout()) {
|
||||||
long offlineCount = redisCache.incrementCacheValue(incrementCacheKey, 60, TimeUnit.SECONDS);
|
long offlineCount = redisCache.incrementCacheValue(incrementCacheKey, 60, TimeUnit.SECONDS);
|
||||||
if (offlineCount >= 1) {
|
if (offlineCount >= 2) {
|
||||||
status = DeviceOnlineStatus.OFFLINE.getStatus();
|
status = DeviceOnlineStatus.OFFLINE.getStatus();
|
||||||
} else {
|
} else {
|
||||||
status = DeviceOnlineStatus.ONLINE.getStatus();
|
status = DeviceOnlineStatus.ONLINE.getStatus();
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package com.ruoyi.ss.user.mapper;
|
package com.ruoyi.ss.user.mapper;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
import com.ruoyi.common.core.domain.entity.SmUser;
|
import com.ruoyi.common.core.domain.entity.SmUser;
|
||||||
import com.ruoyi.ss.user.domain.SmUserQuery;
|
import com.ruoyi.ss.user.domain.SmUserQuery;
|
||||||
import com.ruoyi.ss.user.domain.SmUserVO;
|
import com.ruoyi.ss.user.domain.SmUserVO;
|
||||||
import org.apache.ibatis.annotations.Param;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 普通用户信息Mapper接口
|
* 普通用户信息Mapper接口
|
||||||
|
@ -66,16 +67,6 @@ public interface SmUserMapper
|
||||||
|
|
||||||
int selectCount(SmUserQuery dto);
|
int selectCount(SmUserQuery dto);
|
||||||
|
|
||||||
/**
|
|
||||||
* 增加余额
|
|
||||||
* @param userId 用户id
|
|
||||||
* @param amount 金额
|
|
||||||
* @param beforeBalance 变动前的余额(并发)
|
|
||||||
*/
|
|
||||||
int addBalance(@Param("userId") Long userId,
|
|
||||||
@Param("amount") BigDecimal amount,
|
|
||||||
@Param("beforeBalance") BigDecimal beforeBalance
|
|
||||||
);
|
|
||||||
|
|
||||||
SmUserVO selectSmUserByWxOpenId(String openId);
|
SmUserVO selectSmUserByWxOpenId(String openId);
|
||||||
|
|
||||||
|
@ -106,12 +97,19 @@ public interface SmUserMapper
|
||||||
* @param userId 用户id
|
* @param userId 用户id
|
||||||
* @param amount 金额
|
* @param amount 金额
|
||||||
* @param check 校验余额是否充足
|
* @param check 校验余额是否充足
|
||||||
* @param beforeBalance 变动前的余额(并发)
|
|
||||||
*/
|
*/
|
||||||
int subtractBalance(@Param("userId") Long userId,
|
int subtractBalance(@Param("userId") Long userId,
|
||||||
@Param("amount") BigDecimal amount,
|
@Param("amount") BigDecimal amount,
|
||||||
@Param("check") boolean check,
|
@Param("check") boolean check
|
||||||
@Param("beforeBalance") BigDecimal beforeBalance
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 增加余额
|
||||||
|
* @param userId 用户id
|
||||||
|
* @param amount 金额
|
||||||
|
*/
|
||||||
|
int addBalance(@Param("userId") Long userId,
|
||||||
|
@Param("amount") BigDecimal amount
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -146,4 +144,11 @@ public interface SmUserMapper
|
||||||
* 解除实名认证
|
* 解除实名认证
|
||||||
*/
|
*/
|
||||||
int resetRealName(Long userId);
|
int resetRealName(Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询用户余额
|
||||||
|
*/
|
||||||
|
BigDecimal selectBalanceForUpdate(@Param("userId") Long userId);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -286,12 +286,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
where user_id = #{userId} and del_flag = '0'
|
where user_id = #{userId} and del_flag = '0'
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
<update id="addBalance">
|
|
||||||
update sm_user
|
|
||||||
set balance = balance + #{amount}
|
|
||||||
where user_id = #{userId} and del_flag = '0' and balance = #{beforeBalance}
|
|
||||||
</update>
|
|
||||||
|
|
||||||
<update id="updateSmUser" parameterType="SmUser">
|
<update id="updateSmUser" parameterType="SmUser">
|
||||||
update sm_user
|
update sm_user
|
||||||
<trim prefix="SET" suffixOverrides=",">
|
<trim prefix="SET" suffixOverrides=",">
|
||||||
|
@ -362,13 +356,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<update id="subtractBalance">
|
<update id="subtractBalance">
|
||||||
update sm_user
|
update sm_user
|
||||||
set balance = balance - #{amount}
|
set balance = balance - #{amount}
|
||||||
<where>
|
where user_id = #{userId} and del_flag = '0'
|
||||||
user_id = #{userId} and del_flag = '0' and balance = #{beforeBalance}
|
<if test="check">
|
||||||
<if test="check">
|
and balance >= #{amount}
|
||||||
and balance >= #{amount}
|
</if>
|
||||||
</if>
|
</update>
|
||||||
|
|
||||||
</where>
|
<update id="addBalance">
|
||||||
|
update sm_user
|
||||||
|
set balance = balance + #{amount}
|
||||||
|
where user_id = #{userId} and del_flag = '0'
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
<update id="updateServiceRate">
|
<update id="updateServiceRate">
|
||||||
|
@ -426,4 +423,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
from sm_user su
|
from sm_user su
|
||||||
where su.phonenumber = #{phonenumber} and su.del_flag != '2'
|
where su.phonenumber = #{phonenumber} and su.del_flag != '2'
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- selectBalanceForUpdate -->
|
||||||
|
|
||||||
|
<select id="selectBalanceForUpdate">
|
||||||
|
select balance
|
||||||
|
from sm_user
|
||||||
|
where user_id = #{userId} and del_flag = '0'
|
||||||
|
for update
|
||||||
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
|
@ -231,19 +231,19 @@ public class UserServiceImpl implements UserService
|
||||||
if (BigDecimal.ZERO.compareTo(amount) == 0) {
|
if (BigDecimal.ZERO.compareTo(amount) == 0) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
// 查询用户余额
|
||||||
// 查询用户
|
BigDecimal balance = smUserMapper.selectBalanceForUpdate(userId);
|
||||||
SmUserVO user = selectSmUserByUserId(userId);
|
ServiceUtil.assertion(balance == null, "增加ID为%s的用户余额%s元失败,请重试", userId, amount);
|
||||||
|
|
||||||
// 修改余额
|
// 修改余额
|
||||||
int updateCount = smUserMapper.addBalance(userId, amount, user.getBalance());
|
int update = smUserMapper.addBalance(userId, amount);
|
||||||
ServiceUtil.assertion(updateCount != 1, "增加用户余额失败,请重试");
|
ServiceUtil.assertion(update != 1, "增加用户余额失败,请重试");
|
||||||
|
|
||||||
// 余额变动记录
|
// 余额变动记录
|
||||||
int record = recordBalanceService.record(userId, user.getBalance(), amount, reason, bstType, bstId);
|
int record = recordBalanceService.record(userId, balance, amount, reason, bstType, bstId);
|
||||||
ServiceUtil.assertion(record != 1, "用户余额变动记录失败");
|
ServiceUtil.assertion(record != 1, "用户余额变动记录失败");
|
||||||
|
|
||||||
return updateCount;
|
return update;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -259,18 +259,19 @@ public class UserServiceImpl implements UserService
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询用户
|
// 查询用户余额
|
||||||
SmUserVO user = selectSmUserByUserId(userId);
|
BigDecimal balance = smUserMapper.selectBalanceForUpdate(userId);
|
||||||
|
ServiceUtil.assertion(balance == null || balance.compareTo(amount) < 0, "减少ID为%s的用户余额%s元失败,请重试", userId, amount);
|
||||||
|
|
||||||
// 更新用户余额
|
// 更新用户余额
|
||||||
int updateCount = smUserMapper.subtractBalance(userId, amount, check, user.getBalance());
|
int update = smUserMapper.subtractBalance(userId, amount, check);
|
||||||
ServiceUtil.assertion(updateCount != 1, "减少ID为%s的用户余额%s元失败,请重试", userId, amount);
|
ServiceUtil.assertion(update != 1, "减少ID为%s的用户余额%s元失败,请重试", userId, amount);
|
||||||
|
|
||||||
// 余额变动记录
|
// 余额变动记录
|
||||||
int record = recordBalanceService.record(userId, user.getBalance(), amount.negate(), reason, bstType, bstId);
|
int record = recordBalanceService.record(userId, balance, amount.negate(), reason, bstType, bstId);
|
||||||
ServiceUtil.assertion(record != 1, "记录ID为%s的用户余额变动记录%s元失败", userId, amount);
|
ServiceUtil.assertion(record != 1, "记录ID为%s的用户余额变动记录%s元失败", userId, amount);
|
||||||
|
|
||||||
return updateCount;
|
return update;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user