美文网首页测试开发栈
一个多线程bug引发的测试思考

一个多线程bug引发的测试思考

作者: 测试开发栈 | 来源:发表于2018-06-04 14:17 被阅读14次

背景

今天收到测试的一个bug反馈,bug描述:author表中存在重复的作者信息,在提测时我有说明task解析页面后获得作者信息会按authorId 判断DB中是否已经存在,存在了则不往DB中插入,这本是一个很简单的点,可是代码部署到测试环境后,发现还是插入了2条重复authorId 的数据……

调试

1、MySQLauthor表中数据结构:

fid authorId name ……
10025 a600456 张三 ……
10698 a600456 张三 ……

2、走读对应代码发现没毛病啊,基本逻辑代码如下:

public void parseResult() {
        String html = getHttpResponse();
        Author author = new Author();
        Document document = Jsoup.parse(html);
        String authorId = document.select("a[data-id]").attr("data-id");

        boolean isNotExisted = authorDao.checkExistedById(authorId ) == 0;//查询DB指定ID的记录数
        if(isNotExisted) {
            author.setAuthorName(name);
            author.setAuthorId(authorId );
            ……
            authorDao.insertAuthor(author);
        }

authorDao.checkExistedById(authorId ) 对应的查询SQL:

<select id="checkExistedById" resultType="Integer">
        SELECT COUNT(*)
        FROM T_GALAXY_AUTHOR
        WHERE FAUTHOR_ID = #{authorId}
</select>

后来考虑到并发场景,在多线程环境下task之间是并行的,那么当同一时点有多个task在处理同一个作者时就可能出现重复插入,如下图:


如何解决?

既然是在异步并发场景下出现的数据状态不一致问题,那么就可以利用上一篇文章讲的synchronized关键字来处理,比如用synchronized定义上面的方法为同步方法,这样在多线程场景下,执行到该方法时就变成同步了(即同一时点只有一个线程执行该方法);

public synchronized void parseResult() {
    ……
}

或者对authorId加锁,用synchronized设置同步代码块,也是一样的。

public void parseResult() {
    ……
    String authorId = document.select("a[data-id]").attr("data-id");
    synchronized (authorId) {
        boolean isNotExisted = authorDao.checkExistedById(authorId ) == 0;//查询DB指定ID的记录数
        if(isNotExisted) {
            author.setAuthorName(name);
            author.setAuthorId(authorId );
            ……
            authorDao.insertAuthor(author);
        }
    }
}

又或者我不想再改代码了,从数据库的角度,给author表设置唯一索引,这样也可以保证记录的唯一性了,当然这些问题最好是在建表时就要考虑好,SQL:

ALTER TABLE `T_AUTHOR` ADD UNIQUE KEY UNIQ_AUTHOR_ID (`authorId`);

思考

上面的这些问题,是从开发的角度分析并提供的解决方法,考虑到实际工作中很多测试童鞋对多线程并不了解,也很少主动去学习这一部分,我希望通过这篇文章的分析和思考引起测试童鞋对多线程学习的重视(老实说学会了它你测试的深度可以深深深很多!!!)……那么反过来从测试的角度,我们应该如何发现这样的问题?
1、首先当然是要分析系统中哪些点可能会出现并发问题:
比如常见的往数据库增删改数据的操作,这个肯定得保证事务一致性,所以这些点都是需要并发验证的(你们平时有下意识的去测试这些点吗?)。

2、然后模拟并发场景:
1)对于UI界面,我们可以借助自动化测试来模拟多用户并发场景;
2)对于接口,我们可以借助jmeter来模拟并发场景或者自己直接写代码开多线程模拟并发请求等;
3)其他服务或操作,写代码开多线程模拟;

考虑到实际应用中,很多测试童鞋还不知道如何使用多线程,我就举个简单的应用例子供大家依葫芦画瓢,利用多线程去并发多次请求一个接口:

/**
 * Created by alany on 2018/5/17.
 */
public class MultiThreadsDemo {

    public static void main(String[] args) throws InterruptedException {
        RunnerThread[] threads = new RunnerThread[10];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new RunnerThread("Runner"+ i);
            threads[i].start();
        }

        for (int i = 0; i < threads.length; i++) {
            threads[i].join(); //等所有子线程都执行完,主线程才停止
        }
    }

    static class RunnerThread extends Thread{
        String name;
        public RunnerThread(String name){
            this.name = name;
        }
        @Override
        public void run() {
            String url = "http://api.fixer.io/latest?base=CNY";
            HttpResponse response = new HttpRequest(url) //使用的是之前接口自动化的http请求框架,不清楚可以参考之前的文章
                    .setHeaders(null)
                    .setParams(null)
                    .doGet();
            try {
                String result = EntityUtils.toString(response.getEntity());
                System.out.println("Thread " + name + " response: " + result);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

看下运行效果:


原文来自下方公众号,转载请联系作者,并务必保留出处。
想第一时间看到更多原创技术好文和资料,请关注公众号:测试开发栈

相关文章

  • 一个多线程bug引发的测试思考

    背景 今天收到测试的一个bug反馈,bug描述:author表中存在重复的作者信息,在提测时我有说明task解析页...

  • Mac开发之一个Bug引发的三个思考

    既然是一个Bug引发的思考,自然要先上Bug,如上动图所示,在输入了空格标题之后,引发一个问题,就是光标依然在文本...

  • 一个bug引发的思考

    事情是这样的,一个商品线的小哥哥,找到我,说有批货,不小心入库了两次,一笔在海外转运虚拟仓,一笔在杭州保税仓,于是...

  • 《bug引发的思考-----layoutIfNeeded》

    由来:tableView滚定到某一组的某一行的时候会出现遮挡.也就是多滚动了一点。 楼主的做法是: // 无遮挡的...

  • 测试人员的bug规范模板

    测试人员提bug需要固定充足的证据链并且加入自己的思考分析问题原因 才是一个方便开发修改的bug 按照规范的bug...

  • 推进BUG的解决

    【情景】项目已测试完毕,进入处理BUG的阶段。然而,开发人员各种忙,无暇顾及。 【思考】如果BUG没有解决,测试的...

  • 一个测试引发的思考

    这场测试结果引发了我对自己沟通风格的回顾,在生活中,妈妈让我帮忙存手机号码,我会鼓励她自我尝试动手练习,邓肯在外抢...

  • 一个测试引发的思考.

    头马官网中pathways的沟通测试共有主动型,直接型,支持型,分析型四种,通过测试,我属于支持型,这种类型的沟通...

  • 一个测试引发的思考

    上周锦丹提到的四种沟通方式大家还记得吗?主动型,直接型,支持型,分析型。通过pathways的测试,我是支持型,这...

  • 日记-2020-07-27

    早上:学习vim中午:休息白天: 配合测试 修改批量查询bug 整理面试题-多线程2 整理面试题-JVM部分 待完成

网友评论

    本文标题:一个多线程bug引发的测试思考

    本文链接:https://www.haomeiwen.com/subject/loredftx.html