Java问题记录——循环里的二次判断与状态更新

摘要:本文主要记录了在循环操作时可能出现的问题。

问题重现

在使用循环结构时,如果使用了定时任务,或者代码会多次调用循环结构,可能会导致有些对象会被循环多次。

举例来说,如果有一个结账的代码,每五分钟会执行一次:

  1. @Scheduled(cron = "0 0/5 * * * ?")
  2. @Async
  3. public void handle(){
  4. List<Customer> list = customerDao.listCustomerByStatus(0);// ["zhangsan", "lisi"]
  5. for (Customer customer : list) {
  6. customerDao.updateCustomerStatus(customer.getName(), 1);// 表示正在结账
  7. // 结账代码
  8. customerDao.updateCustomerStatus(customer.getName(), 2);// 表示结账完成
  9. }
  10. }

假设结账代码的执行时间太长,超过了五分钟。

第一次触发定时任务时,查询到状态为0的顾客有ZhangSan和LiSi,进入循环代码块,将ZhangSan的状态改成1并执行结账代码。

由于结账代码执行时间超过了五分钟,所以当下一次定时任务触发的时候,ZhangSan还在执行结账的代码,这时LiSi的状态还是0。

第二次触发定时任务时,查询到状态为0的顾客有LiSi,进入循环代码块,将LiSi的状态改成1并执行结账代码。

当第一次触发的定时任务执行完ZhangSan的结账代码时,循环执行下一个顾客LiSi的结账代码,而此时第二次触发的定时任务已经在执行LiSi的结账代码了,这就会导致顾客LiSi的结账代码被重复执行了两次。

解决办法

第一种办法是先循环一遍查到的数据,将状态改为1,然后执行循环对每一个顾客结账。

第二种办法是重新判断状态,在每次循环执行结账代码时,都重新查询一下顾客的状态,不过这种方式需要每次都查询数据库。

问题说明

在使用循环代码的时候要注意是否有状态的改变,如果有的话就需要考虑是否存在重复处理的隐患。

Java问题记录——循环里的二次判断与状态更新的更多相关文章

  1. Java中的循环结构(二)

    循环结构(二) 学习本章有道的单词: rate:速度,比率 young:年轻的,年少 schedule:时间表,调度 neggtive:消极的;否定 customer:顾客,观众 birthday:生 ...

  2. Java进阶篇设计模式之十二 ---- 备忘录模式和状态模式

    前言 在上一篇中我们学习了行为型模式的策略模式(Strategy Pattern)和模板模式(Template Pattern).本篇则来学习下行为型模式的两个模式,备忘录模式(Memento Pat ...

  3. java面试记录一:跳表、判断二叉树相同、冒泡排序、cookie和session的区别、设计模式(单例、工厂、模板方法、原型、代理、策略)、抽象类与接口的区别

    1.什么是跳表? 跳表实际上就是多层链表 跳表可用在让链表的元素查询接近线性时间 代码结构及java实现参考博客园随笔 2.判断两棵二叉树是否相同?(结构相同,内容相同) 思路:(1)先定义树节点Tr ...

  4. 为什么阿里巴巴Java开发手册中强制要求不要在foreach循环里进行元素的remove和add操作?

    在阅读<阿里巴巴Java开发手册>时,发现有一条关于在 foreach 循环里进行元素的 remove/add 操作的规约,具体内容如下: 错误演示 我们首先在 IDEA 中编写一个在 f ...

  5. Java线程池使用和分析(二) - execute()原理

    相关文章目录: Java线程池使用和分析(一) Java线程池使用和分析(二) - execute()原理 execute()是 java.util.concurrent.Executor接口中唯一的 ...

  6. Java数据结构与算法解析(十二)——散列表

    散列表概述 散列表就是一种以 键-值(key-indexed) 存储数据的结构,我们只要输入待查找的值即key,即可查找到其对应的值. 散列表的思路很简单,如果所有的键都是整数,那么就可以使用一个简单 ...

  7. 第3章 Java数组(上): 一维数组和二维数组

    3.数组及排序算法(2天) 3.1 数组的概述 2课时 3.2 一维数组的使用 3课时 3.3 多维数组的使用 3课时 3.4 数组中涉及到的常见算法 3课时 3.5 Arrays工具类的使用 3课时 ...

  8. 20172302 《Java软件结构与数据结构》实验二:树实验报告

    课程:<Java软件结构与数据结构> 班级: 1723 姓名: 侯泽洋 学号:20172302 实验教师:王志强老师 实验日期:2018年11月5日 必修/选修: 必修 实验内容 (1)参 ...

  9. 第三节 java 数组(循环遍历、获取数组的最值(最大值和最小值)、选择排序、冒泡排序、练习控制台输出大写的A)

    获取数组的最值(最大值和最小值) 思路: 1.获取最值需要进行比较,每一次比较都会有一个较大的值,因为该 值不确定,需要一个变量进行临储. 2.让数组中的每一个元素都和这个变量中的值进行比较,如果大于 ...

随机推荐

  1. js对象的直接赋值、浅拷贝与深拷贝

    最近Vue项目中写到一个业务,就是需要把对话框的表单中的数据,每次点击提交之后,就存进一个el-table表格中,待多次需要的表单数据都提交进表格之后,再将这个表格提交,实现多个表单数据的同时提交,期 ...

  2. python常见字符串操作

    附: python2.x和python3.x中raw_input( )和input( )区别: 备注:1.在python2.x中raw_input( )和input( ),两个函数都存在,其中区别为r ...

  3. 【Android - 组件】之IntentFilter的匹配规则

    我们知道,Activity的启动模式分为两种,分别是显式启动和隐式启动.显式启动需要明确的指定被启动的对象的组件信息,包括包名和类名:而隐式启动需要 Intent 能够匹配目标组件的 IntentFi ...

  4. 【Luogu P3174 】[HAOI2009]毛毛虫

    前言: 虽然很多人和我想法一样 ,但我还是不要脸地写了这题解 题目: 链接 大意: 在一棵树上取一条最长链以及它所连接的结点总共的结点个数 思路: 取链: 用树形\(DP\)就可以轻而易举的解决这个问 ...

  5. Jpa支持LocalDateTime类型持久化

    package com.boldseas.porscheshop.common.config; import javax.persistence.AttributeConverter; import ...

  6. PHP根据经纬度获取在范围坐标的数据

    // 计算范围,可以做搜索用户 function GetRange($lat,$lon,$raidus){ //计算纬度 $degree = (24901 * 1609) / 360.0; $dpmL ...

  7. 小白的springboot之路(八)、继承Redis以及@Cacheable注解实现Redis缓存

    0.前言 在项目中,缓存作为一种高效的提升性能的手段,几乎必不可少,Redis作为其中的佼佼者被广泛应用: 一.spring boot集成Redis 1.添加依赖 <dependency> ...

  8. 一条数据的HBase之旅,简明HBase入门教程3:适用场景

    [摘要] 这篇文章继HBase数据模型之后,介绍HBase的适用场景,以及与一些关键场景有关的周边技术生态,最后给出了本文的示例数据 华为云上的NoSQL数据库服务CloudTable,基于Apach ...

  9. Spring Data-Spring整合Hibernate基于JPA规范

    JPA:由 Sun 公司提供了一对对于持久层操作的标准(接口+文档) Hibernate:是 Gavin King 开发的一套对于持久层操作的自动的 ORM 框架. Hibernate JPA:是在 ...

  10. 洛谷 题解 P1083 【借教室】

    0x00 先看数据范围 $ 1≤n,m≤10^6 $,第一反应 \(O(nlogn)\) 0x01 5 pts 直接输出 '0' 即可. 不要问我怎么知道输出 '0' 可以拿 5 pts. 保持微笑. ...