案例07-在线人员列表逻辑混乱-ThreadLocal、继承、索引失效

简介: 案例07-在线人员列表逻辑混乱-ThreadLocal、继承、索引失效

背景介绍

本篇博客是对在线人员列表逻辑混乱,前端数据显示出现问题,反例进行的总结和进行的改进。

现状:

1、类中写了公共变量最后导致数据混乱现象

2、保存数据没有考虑业务的隔夜覆盖导致的逻辑漏洞

3、涉及到继承,对于this,如果父类有同样的成员最终使用哪一个?

4、参数不一致导致后续维护混乱

5、mysql由于关联字段类型不一致导致产生索引失效问题,进而产生慢sql

6、sql不考虑业务导致有明显的逻辑漏洞

上述问题可以分为四类:

1、变量作用域太大

2、后端逻辑本身有问题

3、继承问题,this.属性,和方法具体使用的是哪个

4、mysql索引失效

思路&方案

一、类中公共变量由于线程共享,导致的数据混乱(公共变量)

所有线程都可以修改全局变量的数据

当咱们不使用多线程的时候不会出现数据错乱的问题,但是当使用多线程且同时修改这个全局变量的时候,就会出现问题了。

解决方法:使用ThreadLocal变量

创建了一个 ThreadLocal类型名为localVar的变量,并且赋初值为 默认localVar

一个打印 localVar值的print()方法

main方法 创建了两个线程:

1、第一个线程操作修改了localVar的值

2、第二个线程直接打印了localVar的值

package org.example;
public class Main {
    static ThreadLocal<String> localVar = ThreadLocal.withInitial(() -> "默认localVar");
    static void  print(String str){
        //打印当前线程内存储的本地变量的值
        System.out.println( str +"   de~~~   " + localVar.get());
    }
    public static void main(String[] args) {
        //创建线程一
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                //打印一下localvar的值
                System.out.println("thread1线程" + localVar.get());
                //修改一下localvar的值
                localVar.set("thread1的local");
                //打印
                print("thread1");
            }
        });
        thread1.start();
        //创建线程二
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程二不共享localVar变量,值为默认值" + localVar.get());
            }
        });
        thread2.start();
    }
}

结论: ThreadLocal 定义的变量是线程安全的

结果:从结果上我们可以看出 第一个线程修改了我们定义的localVar的值之后,第二个线程打印的仍是我们一开始初始化设置的默认值

二、后端本身逻辑漏洞

2、保存数据没有考虑到跨天的问题

在查询的逻辑里添加了 createDate的字段,这里的createDate是按照天取得年月日。如果跨天就会出现问题。

4、参数不一致,导致无法维护

登录状态问题,这里的状态在之前的业务里,已经传入了,但是后续却用了一个魔法值表示,虽然功能上没有出现问题,但是却多了一个写死的值,不利于复用。

6、sql不考虑业务

此sql对应的是教师进行结课之后,将学生的最近登录时间修改。这里存在两个问题。

update_time字段的使用,这个是我们数据库建表规范必备三字段(id,create_time,update_time)之一,业务需要应该新建字段,而不是使用update_time字段

额外添加了createDate字段,用当天时间做为where条件,如果跨天的话,就会出现下线状态无法更新问题。

三、继承(this)

java中继承关系的父子类,相同的方法会被重写

当子类父类中的成员没有重名时,子类都可以通过this去调用。

当成员方法 重名,子类就会将父类中的方法进行重写。如果还想调用父类中的方法只能通过 super去进行调用。

当时成员变量不存在覆盖重写:在子类中只能通过super调用父类的

四、索引失效

索引会因为 隐示数据转换造成 索引失效的问题。在设置外键的时候,一定要保持与相对应的主键的数据类型一致,否则查询的时候,就会出现不走索引的慢sql,多表联查的时候注意条件的数据类型要保持一致。

总结

边界清晰,胆大心细,是写好代码的重中之重。

相关文章
|
3月前
|
分布式计算 DataWorks 数据处理
DataWork数据处理问题之属性覆盖掉如何解决
DataWork数据处理是指使用DataWorks平台进行数据开发、数据处理和数据治理的活动;本合集将涵盖DataWork数据处理的工作流程、工具使用和问题排查,帮助用户提高数据处理的效率和质量。
27 0
|
10月前
|
SQL 安全 关系型数据库
案例07-在线人员列表逻辑混乱
在线人员列表逻辑混乱
|
10月前
|
SQL 安全 Java
28个案例问题分析---007---在线人员逻辑反例--ThreadLocal、继承、索引失效、
28个案例问题分析---007---在线人员逻辑反例--ThreadLocal、继承、索引失效、
47 0
|
10月前
|
安全 搜索推荐
如何避免写重复代码?两种常见的方法:抽象和组合
如何避免写重复代码?两种常见的方法:抽象和组合
155 0
|
11月前
|
存储 JSON 前端开发
Android数据库存储模块封装,让操作记录更好用可复用
Android数据库存储模块封装,让操作记录更好用可复用
|
测试技术 数据库 Python
软件测试面试题:不可逆的操作,如何处理,比如删除一个订单这种接口如何测试
软件测试面试题:不可逆的操作,如何处理,比如删除一个订单这种接口如何测试
162 0
|
前端开发
前端工作总结263-判断绑定逻辑
前端工作总结263-判断绑定逻辑
39 0
|
前端开发
前端工作总结126-代码中的删除逻辑处理
前端工作总结126-代码中的删除逻辑处理
78 0
前端工作总结126-代码中的删除逻辑处理
|
JavaScript 前端开发
前端案例:我的备忘录(支持事件的增加、删除和修改,代码完整)
前端案例:我的备忘录(支持事件的增加、删除和修改,代码完整)
214 0
前端案例:我的备忘录(支持事件的增加、删除和修改,代码完整)
|
数据库 索引
存在逻辑删除的表字段上建立唯一索引的巧办法 (逻辑删除与唯一索引)
设计数据库唯一索引时,经常会碰到唯一删除的键值,导致很难处理,这里就简单介绍一种巧办法,帮你快速解决该问题
1745 0
存在逻辑删除的表字段上建立唯一索引的巧办法 (逻辑删除与唯一索引)