12.23软工踩坑
1.2024年7.4-7.8学习总结/暑假day7-112.2024.6.6学习java&算法3.2024年6.7--6.17学习总结4.2024年7.3学习总结/暑假day65.2024年6.27-7.2学习总结/暑假day1--56.2024年6.23-6.26学习总结7.2024年6.18-6.22学习总结8.2024年7.9-7.19学习总结/暑假day12-229.2024年7.26-7.29学习总结/day29-3210.编程日记 批量导入数据11.编程日记 后端使用redis12.编程日记 更改redis存储默认序列化器13.ide启动多个实例14.session和cookie15.java多线程16.bupt_os_lab117.11.12 ali-oss上传图片18.sql 166119.bupt_os_lab220.11.18 学习21.11.21 打工22.IntelliJ IDEA格式化快捷键失效23.leetcode78 子集24.leetcode39 组合总和25.11.30学习日记26.12.6详解前后端对接27.2024.12.9 小bug
28.12.23软工踩坑
29.leetcode 104530.2024.12.26 os lab331.2024.12.27复习日记32.一文搞定宝塔LINUX部署上线前后端分离项目33.2025.1.2复习34.leetcode 178935.leetcode131 分割回文串36.2025.1.13 redis乱码问题解决37.2025.1.15 学习38.2025.2.17 学习39.2025.2.18 学习40.2025.2.19 学习41.2025.2.24学习42.git clone问题解决43.2025.2.27 学习44.2025.3.4 学习12.23软工踩坑
这里应该是alterRoomNumber
这段代码也有问题
要加一句
如下:
if (waitqueueThis.getIsWaiting()==1){
//如果在等待中,更新等待时间
Date lastRequestTime = waitqueueThis.getLastRequestTime();
LocalDateTime nowTime = LocalDateTime.now();
LocalDateTime lastRequestTimeLocal = LocalDateTime.ofInstant(lastRequestTime.toInstant(), ZoneId.systemDefault());
Duration duration = Duration.between(lastRequestTimeLocal, nowTime);
long seconds = duration.toSeconds();
waitqueueService.lambdaUpdate().eq(Waitqueue::getRoomNum, room_number)
.set(Waitqueue::getWaitingTime, waitqueueThis.getWaitingTime().add(BigDecimal.valueOf(seconds)))
.set(Waitqueue::getLastRequestTime,new Date())
.update();
}
我们看下面这段代码,里面藏着一个很隐蔽的问题
@Override
public StatusRsp getAirconditioner(Long room_number) {
int totalUsingNum = 0;
Airconditioner airconditioner = this.lambdaQuery().eq(Airconditioner::getId, room_number).one();
Room room = roomService.lambdaQuery().eq(Room::getRoomNumber, room_number).one();
Waitqueue waitqueueThis = waitqueueService.lambdaQuery().eq(Waitqueue::getRoomNum, room_number).one();
if (waitqueueThis.getIsWaiting() == 1) {
//如果在等待中,更新等待时间
Date lastRequestTime = waitqueueThis.getLastRequestTime();
LocalDateTime nowTime = LocalDateTime.now();
LocalDateTime lastRequestTimeLocal = LocalDateTime.ofInstant(lastRequestTime.toInstant(), ZoneId.systemDefault());
Duration duration = Duration.between(lastRequestTimeLocal, nowTime);
long seconds = duration.toSeconds();
waitqueueService.lambdaUpdate().eq(Waitqueue::getRoomNum, room_number)
.set(Waitqueue::getWaitingTime, waitqueueThis.getWaitingTime().add(BigDecimal.valueOf(seconds)))
.set(Waitqueue::getLastRequestTime, new Date())
.update();
}
List<Airconditioner> airconditionerList = this.lambdaQuery().list();
int rate = airconditioner.getSpeed();
//如果使用空调数小于3,则可以将等待队列中的空调启动
for (Airconditioner airconditioner1 : airconditionerList) {
if (airconditioner1.getPower() == 1) {
totalUsingNum++;
}
}
List<Waitqueue> list = waitqueueService.lambdaQuery().eq(Waitqueue::getIsWaiting, 1)
.orderBy(true, false, Waitqueue::getLastRequestTime)
.list();
List<Airconditioner> usingACList = this.lambdaQuery()
.eq(Airconditioner::getPower, 1)
.orderBy(true, false, Airconditioner::getAcUsageTime)
.list();
String alterRoomNumber = null;
if (usingACList.size() > 0) {
Airconditioner alterAC = usingACList.get(0);
alterRoomNumber = alterAC.getRoomId();
}
int size = list.size();//等待中的空调数量
if (totalUsingNum < 3 && size > 0) {
int canUseNum = 3 - totalUsingNum;
log.info("等待队列中的空调(按照上次调用时间降序):{}", list);
for (int i = 0; i < Math.min(canUseNum, size); i++) {
int num = list.get(i).getRoomNum();
//将等待时间超过20s的空调开启,并且移出等待队列
this.lambdaUpdate().eq(Airconditioner::getId, num)
.set(Airconditioner::getPower, 1)
.update();
waitqueueService.lambdaUpdate().eq(Waitqueue::getRoomNum, num)
.set(Waitqueue::getIsWaiting, 0)
.set(Waitqueue::getWaitingTime, BigDecimal.valueOf(0))
.update();
}
}
//如果超过三个空调在使用中,需要一个调度算法,找到等待时间超过20s的空调,换掉总使用时间最长的空调
if (totalUsingNum == 3 && size > 0) {
for (Waitqueue waitRoom : list) {
if (waitRoom.getWaitingTime().compareTo(BigDecimal.valueOf(20)) > 0) {
//找到等待时间超过20s的空调,开启
int num = waitRoom.getRoomNum();
this.lambdaUpdate().eq(Airconditioner::getId, num)
.set(Airconditioner::getPower, 1)
.set(Airconditioner::getQueue,0)
.update();
waitqueueService.lambdaUpdate().eq(Waitqueue::getRoomNum, num)
.set(Waitqueue::getIsWaiting, 0)
.set(Waitqueue::getWaitingTime, BigDecimal.valueOf(0))
.set(Waitqueue::getLastRequestTime,new Date())
.set(Waitqueue::getWaitingTime,0)
.update();
//将使用时间最长的空调,关闭
this.lambdaUpdate().eq(Airconditioner::getId, alterRoomNumber)
.set(Airconditioner::getPower, 0)
.set(Airconditioner::getQueue,1)
.update();
waitqueueService.lambdaUpdate().eq(Waitqueue::getRoomNum, alterRoomNumber)
.set(Waitqueue::getIsWaiting, 1)
.set(Waitqueue::getWaitingTime, BigDecimal.valueOf(0))
.set(Waitqueue::getLastRequestTime,new Date())
.set(Waitqueue::getWaitingTime,0)
.update();
}
}
}
List<Waitqueue> waitqueueList = waitqueueService.lambdaQuery().list();
if (airconditioner == null) {
return null;
}
if (airconditioner.getPower() == 1) {
//空调在使用过程中,实时计算费用
LocalDateTime nowTime = LocalDateTime.now();
Date lastStartTime = airconditioner.getLastStartTime();
LocalDateTime lastAcUseTime = LocalDateTime.ofInstant(lastStartTime.toInstant(), ZoneId.systemDefault());
Duration duration = Duration.between(lastAcUseTime, nowTime);
//计算空调距离数据库中的lastUseTime到现在的时间差
long seconds = duration.toSeconds();
//log.info("距离上次使用的秒数:{}", seconds);
BigDecimal fee = BigDecimal.valueOf(1.0 * seconds * airconditioner.getSpeed() / 3 / 60);
//room更新费用
room.setAcFee(room.getAcFee().add(fee));
room.setAcUsageTime(room.getAcUsageTime().add(BigDecimal.valueOf(1.0 * seconds / 3 / 60)));
room.setTotalFee(room.getTotalFee().add(fee));
if (room.getCurrentTemperature().compareTo(airconditioner.getTemperature()) < 0) {
//房间温度小于设定温度
room.setCurrentTemperature(room.getCurrentTemperature().add(BigDecimal.valueOf(1.0 * seconds / 60)));
} else {
//房间温度大于设定温度
BigDecimal subtract = room.getCurrentTemperature().subtract(BigDecimal.valueOf(1.0 * seconds / 60));
room.setCurrentTemperature(room.getCurrentTemperature().subtract(BigDecimal.valueOf(1.0 * seconds / 60)));
}
roomService.lambdaUpdate().eq(Room::getRoomNumber, room_number).update(room);
//airconditioner更新使用时间
airconditioner.setLastStartTime(new Date());
this.lambdaUpdate().eq(Airconditioner::getId, room_number).update(airconditioner);
} else {
//空调未使用,更新房间温度
if (room.getCurrentTemperature().compareTo(BigDecimal.valueOf(room.getEnvironmentTemperature())) < 0) {
//房间温度小于环境温度
roomService.lambdaUpdate().eq(Room::getRoomNumber, room_number)
.set(Room::getCurrentTemperature,
room.getCurrentTemperature().add(BigDecimal.valueOf(RateEnums.getEnumByValue(rate).getText() / 60)));
} else {
//房间温度大于环境温度
roomService.lambdaUpdate().eq(Room::getRoomNumber, room_number)
.set(Room::getCurrentTemperature,
room.getCurrentTemperature().subtract(BigDecimal.valueOf((RateEnums.getEnumByValue(rate).getText() / 60))));
}
}
StatusRsp result = new StatusRsp();
result.setMode(airconditioner.getMode());
result.setSpeed(SpeedEnums.getEnumByValue(airconditioner.getSpeed()).getText());
result.setPower((airconditioner.getPower() == 1));
result.setCost(room.getAcFee());
//queue里面
result.setQueue(String.valueOf(waitqueueThis.getIsWaiting()));
result.setTime(room.getAcUsageTime());
return result;
}
}
问题就出在115行的代码
this.lambdaUpdate().eq(Airconditioner::getId, room_number).update(airconditioner);
本意是想计算出空调使用的时间然后计算费用加到总计费上面,但是用了update(airconditioner),这就出大问题了,因为airconditioner我们是从数据库中查出来的,但是呢,在上面的语句中我们有一个调度的逻辑,也就是说我们可能已经把数据库中空调的开关状态改变了,但是这里又把它还原了!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构