并发下的编程如何避免脏数据,并简单解决!

业务场景:

模拟一个场景,给一个用户的余额充值。如果正常情况会出现什么问题,并发下又会出现什么问题,出现问题又怎么解决,按照这个思路来讲解下并发下的编程如何避免脏数据。

并发可能发生的情况,目前我接触过两大类:1.两次改库操作并发进来,只有一次有效。2.两次一模一样的请求进来,本应该修只改一次,结果修改了两次。(第二种比第一种常见)

这是我们的表:

然后我们手动在数据库添加一条数据,此时阿达这个用户余额为0;

下面的是我们的接口,入参很简单,传用户的id和要充值的钱。业务逻辑很简单,先查一下用户这个对象,然后把金额改变一下,最后入库

这是测试方法:

①正常情况下:我们测试一下,分别运行一下两方法

第一次充值:

第二次充值:

②模拟下并发,在接口的代码里让线程休息5秒,这样做是为了让第一次调用的线程,在改数据之前等下第二个线程。(并发的情况是同时进来的,并不好模拟。这里我们投机一下,让线程等待一下,这样进来的两个线程就跟并发的类似)

我们先把数据库清下,让余额变成0。

看这两次充钱是什么反应

第一次充值:

第二次充值:

我们看下数据库:

明明充了两次钱800+600应该余额1400.但我们的结果却是600,这个就是并发造成的脏数据问题,是个很严重的bug。

解决方案:

1.加悲观锁用synchronized关键字

并发下,第一次充值:

第二次充值:

结果看到了,没有充值错误。

2.乐观锁,给数据库加个版本号

这样修改会比对版本号如果版本号不对,就会修改失败。

总结:

这篇文章主要是通过一个充钱的场景来模拟并发下对数据产生的影响,并给到悲观锁和乐观锁的解决方案。我是阿达,一名喜欢分享知识的程序员,时不时的也会荒腔走板的聊一聊电影、电视剧、音乐、漫画,这里已经有17位小伙伴在等你们啦,感兴趣的就赶紧来点击关注我把,哪里有不明白或有不同观点的地方欢迎留言。

猜你喜欢

转载自blog.csdn.net/jdk_wangtaida/article/details/88431616
今日推荐