项目中并发修改可能存在的问题

Posted 遇见美好,遇见妳

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了项目中并发修改可能存在的问题相关的知识,希望对你有一定的参考价值。

  最近做的一个功能和同事做的工作存在交集,他做的主要是写一张表的增、删、改、查的功能,自己主要负责的是

数据同步功能,从以前的旧系统同步数据到新系统中。自己在写代码的时候发现同事写的代码中有这么一段代码,功能

很简单就是根据ID去查询数据,然后在代码中对该条数据中的某个字段进行加一。自己看到这段代码,立马想到这种写

代码的方式可能存在问题,比如在并发请求的时候,这种方式是会存在问题的,下面来复现一下这个问题。

  写一个简单的测试demo,使用controller,service,dao经典的三层方式。

 

 

 

 

 

 

 

 

 创建一张简单的数据表,把需要更新的字段user_times的值设置为0。为了看得更加清楚,查询的时候多添加了一个查询时间,如下图所示

 

 

 下面的配置简单来说就是在0.5s内启动100个线程来访问后台的接口,并执行3次访问。按照每次加一在计算,user_times的数量应该是300。

 

 

 测试结果一为63.

 

 

 将user_times置为0之后,在测试两次结果为:

 

 

 

 

 

 三次实际测试的结果和预期的结果都不一致,说明这段代码是存在问题的。

问题已经暴露出来,那如何解决这个问题呢?

提供两个解决方法,方法一直接在该方法上加锁,如下图

 

 

 在次测试,结果为300符合预期。

 

 

 方法二,将user_times自增加一的操作放在数据库中去执行,改动如下,service方法修改为如下方法,

 

 

 数据库操作的方法修改为下面的方法,

 

 

 在次清空数据进行测试,结果为300,符合预期。

 

 有兴趣的小伙伴可以自己去写一个简单的测试demo试一试,这样能够更加直观地看到问题。或者是有其他解决办法的朋友,

欢迎留言讨论。

以上是关于项目中并发修改可能存在的问题的主要内容,如果未能解决你的问题,请参考以下文章

Servlet编程专题5之servlet线程安全问题

使用redis分布式锁解决并发线程资源共享问题

数据库并发事务存在的三个问题(脏读不可重复读幻读)

java并发:CopyOnWriteArrayList简单理解

高并发状态下修改数据库的操作

Java并发 chapter3 共享对象